Fix for bug #8555: geometry node front/bake was broken.
[plumiferos.git] / source / blender / blenkernel / intern / node.c
blobf6f374ba297e58aa124255162cccb0d4aeec9ed2
1 /**
2 * $Id: node.c 13017 2007-12-27 10:17:33Z bebraw $
4 * ***** BEGIN GPL LICENSE BLOCK *****
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.
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.
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.
20 * The Original Code is Copyright (C) 2005 Blender Foundation.
21 * All rights reserved.
23 * The Original Code is: all of this file.
25 * Contributor(s): none yet.
27 * ***** END GPL LICENSE BLOCK *****
30 #include <stdlib.h>
31 #include <string.h>
33 #include "DNA_ID.h"
34 #include "DNA_image_types.h"
35 #include "DNA_node_types.h"
36 #include "DNA_material_types.h"
37 #include "DNA_scene_types.h"
39 #include "BKE_blender.h"
40 #include "BKE_colortools.h"
41 #include "BKE_global.h"
42 #include "BKE_image.h"
43 #include "BKE_library.h"
44 #include "BKE_main.h"
45 #include "BKE_node.h"
46 #include "BKE_texture.h"
47 #include "BKE_utildefines.h"
49 #include "BLI_arithb.h"
50 #include "BLI_blenlib.h"
51 #include "BLI_rand.h"
52 #include "BLI_threads.h"
54 #include "PIL_time.h"
56 #include "MEM_guardedalloc.h"
57 #include "IMB_imbuf.h"
59 #include "RE_pipeline.h"
60 #include "RE_shader_ext.h" /* <- TexResult */
61 #include "RE_render_ext.h" /* <- ibuf_sample() */
63 #include "CMP_node.h"
64 #include "intern/CMP_util.h" /* stupid include path... */
66 #include "SHD_node.h"
68 /* not very important, but the stack solver likes to know a maximum */
69 #define MAX_SOCKET 64
71 static ListBase empty_list = {NULL, NULL};
72 ListBase node_all_composit = {NULL, NULL};
73 ListBase node_all_shaders = {NULL, NULL};
75 /* ************** Type stuff ********** */
77 static bNodeType *node_get_type(bNodeTree *ntree, int type, bNodeTree *ngroup)
79 if(type==NODE_GROUP) {
80 if(ngroup && GS(ngroup->id.name)==ID_NT) {
81 return ngroup->owntype;
83 return NULL;
85 else {
86 bNodeType *ntype = ntree->alltypes.first;
87 for(; ntype; ntype= ntype->next)
88 if(ntype->type==type)
89 return ntype;
91 return NULL;
95 void ntreeInitTypes(bNodeTree *ntree)
97 bNode *node, *next;
99 if(ntree->type==NTREE_SHADER)
100 ntree->alltypes= node_all_shaders;
101 else if(ntree->type==NTREE_COMPOSIT)
102 ntree->alltypes= node_all_composit;
103 else {
104 ntree->alltypes= empty_list;
105 printf("Error: no type definitions for nodes\n");
108 for(node= ntree->nodes.first; node; node= next) {
109 next= node->next;
110 node->typeinfo= node_get_type(ntree, node->type, (bNodeTree *)node->id);
111 if(node->typeinfo==NULL) {
112 printf("Error: Node type %s doesn't exist anymore, removed\n", node->name);
113 nodeFreeNode(ntree, node);
117 ntree->init |= NTREE_TYPE_INIT;
120 /* only used internal... we depend on type definitions! */
121 static bNodeSocket *node_add_socket_type(ListBase *lb, bNodeSocketType *stype)
123 bNodeSocket *sock= MEM_callocN(sizeof(bNodeSocket), "sock");
125 BLI_strncpy(sock->name, stype->name, NODE_MAXSTR);
126 if(stype->limit==0) sock->limit= 0xFFF;
127 else sock->limit= stype->limit;
128 sock->type= stype->type;
130 sock->to_index= stype->own_index;
131 sock->tosock= stype->internsock;
133 sock->ns.vec[0]= stype->val1;
134 sock->ns.vec[1]= stype->val2;
135 sock->ns.vec[2]= stype->val3;
136 sock->ns.vec[3]= stype->val4;
137 sock->ns.min= stype->min;
138 sock->ns.max= stype->max;
140 if(lb)
141 BLI_addtail(lb, sock);
143 return sock;
146 static void node_rem_socket(bNodeTree *ntree, ListBase *lb, bNodeSocket *sock)
148 bNodeLink *link, *next;
150 for(link= ntree->links.first; link; link= next) {
151 next= link->next;
152 if(link->fromsock==sock || link->tosock==sock) {
153 nodeRemLink(ntree, link);
157 BLI_remlink(lb, sock);
158 MEM_freeN(sock);
161 static bNodeSocket *verify_socket(ListBase *lb, bNodeSocketType *stype)
163 bNodeSocket *sock;
165 for(sock= lb->first; sock; sock= sock->next) {
166 /* both indices are zero for non-groups, otherwise it's a unique index */
167 if(sock->to_index==stype->own_index)
168 if(strncmp(sock->name, stype->name, NODE_MAXSTR)==0)
169 break;
171 if(sock) {
172 sock->type= stype->type; /* in future, read this from tydefs! */
173 if(stype->limit==0) sock->limit= 0xFFF;
174 else sock->limit= stype->limit;
175 sock->ns.min= stype->min;
176 sock->ns.max= stype->max;
177 sock->tosock= stype->internsock;
179 BLI_remlink(lb, sock);
181 return sock;
183 else {
184 return node_add_socket_type(NULL, stype);
188 static void verify_socket_list(bNodeTree *ntree, ListBase *lb, bNodeSocketType *stype_first)
190 bNodeSocketType *stype;
192 /* no inputs anymore? */
193 if(stype_first==NULL) {
194 while(lb->first)
195 node_rem_socket(ntree, lb, lb->first);
197 else {
198 /* step by step compare */
199 stype= stype_first;
200 while(stype->type != -1) {
201 stype->sock= verify_socket(lb, stype);
202 stype++;
204 /* leftovers are removed */
205 while(lb->first)
206 node_rem_socket(ntree, lb, lb->first);
207 /* and we put back the verified sockets */
208 stype= stype_first;
209 while(stype->type != -1) {
210 BLI_addtail(lb, stype->sock);
211 stype++;
216 void nodeVerifyType(bNodeTree *ntree, bNode *node)
218 bNodeType *ntype= node->typeinfo;
220 if(ntype) {
221 /* might add some other verify stuff here */
223 verify_socket_list(ntree, &node->inputs, ntype->inputs);
224 verify_socket_list(ntree, &node->outputs, ntype->outputs);
228 void ntreeVerifyTypes(bNodeTree *ntree)
230 bNode *node;
232 /* if((ntree->init & NTREE_TYPE_INIT)==0) */
233 ntreeInitTypes(ntree);
235 /* check inputs and outputs, and remove or insert them */
236 for(node= ntree->nodes.first; node; node= node->next)
237 nodeVerifyType(ntree, node);
241 /* ************** Group stuff ********** */
243 bNodeType node_group_typeinfo= {
244 /* next,prev */ NULL, NULL,
245 /* type code */ NODE_GROUP,
246 /* name */ "Group",
247 /* width+range */ 120, 60, 200,
248 /* class+opts */ NODE_CLASS_GROUP, NODE_OPTIONS,
249 /* input sock */ NULL,
250 /* output sock */ NULL,
251 /* storage */ "",
252 /* execfunc */ NULL,
253 /* butfunc */ NULL,
254 /* initfunc */ NULL,
255 /* freestoragefunc */ NULL,
256 /* copystoragefunc */ NULL,
257 /* id */ NULL
260 /* tag internal sockets */
261 static void group_tag_internal_sockets(bNodeTree *ngroup)
263 bNode *node;
264 bNodeSocket *sock;
265 bNodeLink *link;
267 /* clear intern tag, but check already for hidden sockets */
268 for(node= ngroup->nodes.first; node; node= node->next) {
269 for(sock= node->inputs.first; sock; sock= sock->next)
270 sock->intern= sock->flag & SOCK_HIDDEN;
271 for(sock= node->outputs.first; sock; sock= sock->next)
272 sock->intern= sock->flag & (SOCK_HIDDEN|SOCK_UNAVAIL);
274 /* set tag */
275 for(link= ngroup->links.first; link; link= link->next) {
276 link->fromsock->intern= 1;
277 link->tosock->intern= 1;
280 /* remove link pointer to external links (only happens on create group) */
281 for(node= ngroup->nodes.first; node; node= node->next) {
282 for(sock= node->inputs.first; sock; sock= sock->next)
283 if(sock->intern==0)
284 sock->link= NULL;
287 /* set all intern sockets to own_index zero, makes sure that later use won't mixup */
288 for(node= ngroup->nodes.first; node; node= node->next) {
289 for(sock= node->inputs.first; sock; sock= sock->next)
290 if(sock->intern)
291 sock->own_index= 0;
292 for(sock= node->outputs.first; sock; sock= sock->next)
293 if(sock->intern)
294 sock->own_index= 0;
298 /* after editing group, new sockets are zero */
299 /* this routine ensures unique identifiers for zero sockets that are exposed */
300 static void group_verify_own_indices(bNodeTree *ngroup)
302 bNode *node;
303 bNodeSocket *sock;
305 for(node= ngroup->nodes.first; node; node= node->next) {
306 for(sock= node->inputs.first; sock; sock= sock->next)
307 if(sock->own_index==0 && sock->intern==0)
308 sock->own_index= ++(ngroup->cur_index);
309 for(sock= node->outputs.first; sock; sock= sock->next)
310 if(sock->own_index==0 && sock->intern==0)
311 sock->own_index= ++(ngroup->cur_index);
313 //printf("internal index %d\n", ngroup->cur_index);
317 /* nodetrees can be used as groups, so we need typeinfo structs generated */
318 void ntreeMakeOwnType(bNodeTree *ngroup)
320 bNode *node;
321 bNodeSocket *sock;
322 int totin= 0, totout=0, a;
324 /* tags socket when internal linked */
325 group_tag_internal_sockets(ngroup);
327 /* ensure all sockets have own unique id */
328 group_verify_own_indices(ngroup);
330 /* counting stats */
331 for(node= ngroup->nodes.first; node; node= node->next) {
332 if(node->type==NODE_GROUP)
333 break;
334 for(sock= node->inputs.first; sock; sock= sock->next)
335 if(sock->intern==0)
336 totin++;
337 for(sock= node->outputs.first; sock; sock= sock->next)
338 if(sock->intern==0)
339 totout++;
341 /* debug: nodetrees in nodetrees not handled yet */
342 if(node) {
343 printf("group in group, not supported yet\n");
344 return;
347 /* free own type struct */
348 if(ngroup->owntype) {
349 if(ngroup->owntype->inputs)
350 MEM_freeN(ngroup->owntype->inputs);
351 if(ngroup->owntype->outputs)
352 MEM_freeN(ngroup->owntype->outputs);
353 MEM_freeN(ngroup->owntype);
356 /* make own type struct */
357 ngroup->owntype= MEM_callocN(sizeof(bNodeType), "group type");
358 *ngroup->owntype= node_group_typeinfo; /* copy data, for init */
360 /* input type arrays */
361 if(totin) {
362 bNodeSocketType *stype;
363 bNodeSocketType *inputs= MEM_callocN(sizeof(bNodeSocketType)*(totin+1), "bNodeSocketType");
364 a= 0;
366 for(node= ngroup->nodes.first; node; node= node->next) {
367 /* nodes are presumed fully verified, stype and socket list are in sync */
368 stype= node->typeinfo->inputs;
369 for(sock= node->inputs.first; sock; sock= sock->next, stype++) {
370 if(sock->intern==0) {
371 /* debug only print */
372 if(stype==NULL || stype->type==-1) printf("group verification error %s\n", ngroup->id.name);
374 inputs[a]= *stype;
375 inputs[a].own_index= sock->own_index;
376 inputs[a].internsock= sock;
377 a++;
381 inputs[a].type= -1; /* terminator code */
382 ngroup->owntype->inputs= inputs;
385 /* output type arrays */
386 if(totout) {
387 bNodeSocketType *stype;
388 bNodeSocketType *outputs= MEM_callocN(sizeof(bNodeSocketType)*(totout+1), "bNodeSocketType");
389 a= 0;
391 for(node= ngroup->nodes.first; node; node= node->next) {
392 /* nodes are presumed fully verified, stype and socket list are in sync */
393 stype= node->typeinfo->outputs;
394 for(sock= node->outputs.first; sock; sock= sock->next, stype++) {
395 if(sock->intern==0) {
396 /* debug only print */
397 if(stype==NULL || stype->type==-1) printf("group verification error %s\n", ngroup->id.name);
399 outputs[a]= *stype;
400 outputs[a].own_index= sock->own_index;
401 outputs[a].internsock= sock;
402 a++;
406 outputs[a].type= -1; /* terminator code */
407 ngroup->owntype->outputs= outputs;
410 /* voila, the nodetree has the full definition for generating group-node instances! */
414 static bNodeSocket *groupnode_find_tosock(bNode *gnode, int index)
416 bNodeSocket *sock;
418 for(sock= gnode->inputs.first; sock; sock= sock->next)
419 if(sock->to_index==index)
420 return sock;
421 return NULL;
424 static bNodeSocket *groupnode_find_fromsock(bNode *gnode, int index)
426 bNodeSocket *sock;
428 for(sock= gnode->outputs.first; sock; sock= sock->next)
429 if(sock->to_index==index)
430 return sock;
431 return NULL;
434 bNode *nodeMakeGroupFromSelected(bNodeTree *ntree)
436 bNodeLink *link, *linkn;
437 bNode *node, *gnode, *nextn;
438 bNodeSocket *sock;
439 bNodeTree *ngroup;
440 float min[2], max[2];
441 int totnode=0;
443 INIT_MINMAX2(min, max);
445 /* is there something to group? also do some clearing */
446 for(node= ntree->nodes.first; node; node= node->next) {
447 if(node->flag & NODE_SELECT) {
448 /* no groups in groups */
449 if(node->type==NODE_GROUP)
450 return NULL;
451 DO_MINMAX2( (&node->locx), min, max);
452 totnode++;
454 node->done= 0;
456 if(totnode==0) return NULL;
458 /* check if all connections are OK, no unselected node has both
459 inputs and outputs to a selection */
460 for(link= ntree->links.first; link; link= link->next) {
461 if(link->fromnode->flag & NODE_SELECT)
462 link->tonode->done |= 1;
463 if(link->tonode->flag & NODE_SELECT)
464 link->fromnode->done |= 2;
467 for(node= ntree->nodes.first; node; node= node->next) {
468 if((node->flag & NODE_SELECT)==0)
469 if(node->done==3)
470 break;
472 if(node)
473 return NULL;
475 /* OK! new nodetree */
476 ngroup= alloc_libblock(&G.main->nodetree, ID_NT, "NodeGroup");
477 ngroup->type= ntree->type;
478 ngroup->alltypes= ntree->alltypes;
480 /* move nodes over */
481 for(node= ntree->nodes.first; node; node= nextn) {
482 nextn= node->next;
483 if(node->flag & NODE_SELECT) {
484 BLI_remlink(&ntree->nodes, node);
485 BLI_addtail(&ngroup->nodes, node);
486 node->locx-= 0.5f*(min[0]+max[0]);
487 node->locy-= 0.5f*(min[1]+max[1]);
489 /* set selin and selout of the nodetree */
490 for(sock= node->inputs.first; sock; sock= sock->next) {
491 if(sock->flag & SOCK_SEL) {
492 ngroup->selin= sock;
493 break;
496 for(sock= node->outputs.first; sock; sock= sock->next) {
497 if(sock->flag & SOCK_SEL) {
498 ngroup->selout= sock;
499 break;
505 /* move links over */
506 for(link= ntree->links.first; link; link= linkn) {
507 linkn= link->next;
508 if(link->fromnode->flag & link->tonode->flag & NODE_SELECT) {
509 BLI_remlink(&ntree->links, link);
510 BLI_addtail(&ngroup->links, link);
514 /* now we can make own group typeinfo */
515 ntreeMakeOwnType(ngroup);
517 /* make group node */
518 gnode= nodeAddNodeType(ntree, NODE_GROUP, ngroup);
519 gnode->locx= 0.5f*(min[0]+max[0]);
520 gnode->locy= 0.5f*(min[1]+max[1]);
522 /* relink external sockets */
523 for(link= ntree->links.first; link; link= linkn) {
524 linkn= link->next;
526 if(link->tonode->flag & NODE_SELECT) {
527 link->tonode= gnode;
528 sock= groupnode_find_tosock(gnode, link->tosock->own_index);
529 if(sock==NULL) {
530 nodeRemLink(ntree, link);
531 printf("Removed link, cannot mix internal and external sockets in group\n");
533 else link->tosock= sock;
535 else if(link->fromnode->flag & NODE_SELECT) {
536 link->fromnode= gnode;
537 sock= groupnode_find_fromsock(gnode, link->fromsock->own_index);
538 if(sock==NULL) {
539 nodeRemLink(ntree, link);
540 printf("Removed link, cannot mix internal and external sockets in group\n");
542 else link->fromsock= sock;
546 /* initialize variables of unused input sockets */
547 for(node= ngroup->nodes.first; node; node= node->next) {
548 for(sock= node->inputs.first; sock; sock= sock->next) {
549 if(sock->intern==0) {
550 bNodeSocket *nsock= groupnode_find_tosock(gnode, sock->own_index);
551 if(nsock) {
552 QUATCOPY(nsock->ns.vec, sock->ns.vec);
557 return gnode;
560 /* note: ungroup: group_indices zero! */
562 /* here's a nasty little one, need to check users... */
563 /* should become callbackable... */
564 void nodeVerifyGroup(bNodeTree *ngroup)
567 /* group changed, so we rebuild the type definition */
568 ntreeMakeOwnType(ngroup);
570 if(ngroup->type==NTREE_SHADER) {
571 Material *ma;
572 for(ma= G.main->mat.first; ma; ma= ma->id.next) {
573 if(ma->nodetree) {
574 bNode *node;
576 /* find if group is in tree */
577 for(node= ma->nodetree->nodes.first; node; node= node->next)
578 if(node->id == (ID *)ngroup)
579 break;
581 if(node) {
582 /* set all type pointers OK */
583 ntreeInitTypes(ma->nodetree);
585 for(node= ma->nodetree->nodes.first; node; node= node->next)
586 if(node->id == (ID *)ngroup)
587 nodeVerifyType(ma->nodetree, node);
592 else if(ngroup->type==NTREE_COMPOSIT) {
593 Scene *sce;
594 for(sce= G.main->scene.first; sce; sce= sce->id.next) {
595 if(sce->nodetree) {
596 bNode *node;
598 /* find if group is in tree */
599 for(node= sce->nodetree->nodes.first; node; node= node->next)
600 if(node->id == (ID *)ngroup)
601 break;
603 if(node) {
604 /* set all type pointers OK */
605 ntreeInitTypes(sce->nodetree);
607 for(node= sce->nodetree->nodes.first; node; node= node->next)
608 if(node->id == (ID *)ngroup)
609 nodeVerifyType(sce->nodetree, node);
616 /* also to check all users of groups. Now only used in editor for hide/unhide */
617 /* should become callbackable? */
618 void nodeGroupSocketUseFlags(bNodeTree *ngroup)
620 bNode *node;
621 bNodeSocket *sock;
623 /* clear flags */
624 for(node= ngroup->nodes.first; node; node= node->next) {
625 for(sock= node->inputs.first; sock; sock= sock->next)
626 sock->flag &= ~SOCK_IN_USE;
627 for(sock= node->outputs.first; sock; sock= sock->next)
628 sock->flag &= ~SOCK_IN_USE;
631 /* tag all thats in use */
632 if(ngroup->type==NTREE_SHADER) {
633 Material *ma;
634 for(ma= G.main->mat.first; ma; ma= ma->id.next) {
635 if(ma->nodetree) {
636 for(node= ma->nodetree->nodes.first; node; node= node->next) {
637 if(node->id==(ID *)ngroup) {
638 for(sock= node->inputs.first; sock; sock= sock->next)
639 if(sock->link)
640 if(sock->tosock)
641 sock->tosock->flag |= SOCK_IN_USE;
642 for(sock= node->outputs.first; sock; sock= sock->next)
643 if(nodeCountSocketLinks(ma->nodetree, sock))
644 if(sock->tosock)
645 sock->tosock->flag |= SOCK_IN_USE;
651 else if(ngroup->type==NTREE_COMPOSIT) {
652 Scene *sce;
653 for(sce= G.main->scene.first; sce; sce= sce->id.next) {
654 if(sce->nodetree) {
655 for(node= sce->nodetree->nodes.first; node; node= node->next) {
656 if(node->id==(ID *)ngroup) {
657 for(sock= node->inputs.first; sock; sock= sock->next)
658 if(sock->link)
659 if(sock->tosock)
660 sock->tosock->flag |= SOCK_IN_USE;
661 for(sock= node->outputs.first; sock; sock= sock->next)
662 if(nodeCountSocketLinks(sce->nodetree, sock))
663 if(sock->tosock)
664 sock->tosock->flag |= SOCK_IN_USE;
672 /* finds a node based on given socket */
673 int nodeFindNode(bNodeTree *ntree, bNodeSocket *sock, bNode **nodep, int *sockindex)
675 bNode *node;
676 bNodeSocket *tsock;
677 int index= 0;
679 for(node= ntree->nodes.first; node; node= node->next) {
680 for(index=0, tsock= node->inputs.first; tsock; tsock= tsock->next, index++)
681 if(tsock==sock)
682 break;
683 if(tsock)
684 break;
685 for(index=0, tsock= node->outputs.first; tsock; tsock= tsock->next, index++)
686 if(tsock==sock)
687 break;
688 if(tsock)
689 break;
692 if(node) {
693 *nodep= node;
694 if(sockindex) *sockindex= index;
695 return 1;
698 *nodep= NULL;
699 return 0;
702 /* returns 1 if its OK */
703 int nodeGroupUnGroup(bNodeTree *ntree, bNode *gnode)
705 bNodeLink *link, *linkn;
706 bNode *node, *nextn;
707 bNodeTree *ngroup, *wgroup;
708 int index;
710 ngroup= (bNodeTree *)gnode->id;
711 if(ngroup==NULL) return 0;
713 /* clear new pointers, set in copytree */
714 for(node= ntree->nodes.first; node; node= node->next)
715 node->new_node= NULL;
717 wgroup= ntreeCopyTree(ngroup, 0);
719 /* add the nodes into the ntree */
720 for(node= wgroup->nodes.first; node; node= nextn) {
721 nextn= node->next;
722 BLI_remlink(&wgroup->nodes, node);
723 BLI_addtail(&ntree->nodes, node);
724 node->locx+= gnode->locx;
725 node->locy+= gnode->locy;
726 node->flag |= NODE_SELECT;
728 /* and the internal links */
729 for(link= wgroup->links.first; link; link= linkn) {
730 linkn= link->next;
731 BLI_remlink(&wgroup->links, link);
732 BLI_addtail(&ntree->links, link);
735 /* restore links to and from the gnode */
736 for(link= ntree->links.first; link; link= link->next) {
737 if(link->tonode==gnode) {
738 /* link->tosock->tosock is on the node we look for */
739 nodeFindNode(ngroup, link->tosock->tosock, &nextn, &index);
740 if(nextn==NULL) printf("wrong stuff!\n");
741 else if(nextn->new_node==NULL) printf("wrong stuff too!\n");
742 else {
743 link->tonode= nextn->new_node;
744 link->tosock= BLI_findlink(&link->tonode->inputs, index);
747 else if(link->fromnode==gnode) {
748 /* link->fromsock->tosock is on the node we look for */
749 nodeFindNode(ngroup, link->fromsock->tosock, &nextn, &index);
750 if(nextn==NULL) printf("1 wrong stuff!\n");
751 else if(nextn->new_node==NULL) printf("1 wrong stuff too!\n");
752 else {
753 link->fromnode= nextn->new_node;
754 link->fromsock= BLI_findlink(&link->fromnode->outputs, index);
759 /* remove the gnode & work tree */
760 free_libblock(&G.main->nodetree, wgroup);
762 nodeFreeNode(ntree, gnode);
764 /* solve order goes fine, but the level tags not... doing it twice works for now. solve this once */
765 ntreeSolveOrder(ntree);
766 ntreeSolveOrder(ntree);
768 return 1;
771 void nodeCopyGroup(bNode *gnode)
773 bNodeSocket *sock;
775 gnode->id->us--;
776 gnode->id= (ID *)ntreeCopyTree((bNodeTree *)gnode->id, 0);
778 /* new_sock was set in nodeCopyNode */
779 for(sock=gnode->inputs.first; sock; sock=sock->next)
780 if(sock->tosock)
781 sock->tosock= sock->tosock->new_sock;
783 for(sock=gnode->outputs.first; sock; sock=sock->next)
784 if(sock->tosock)
785 sock->tosock= sock->tosock->new_sock;
788 /* ************** Add stuff ********** */
790 bNode *nodeAddNodeType(bNodeTree *ntree, int type, bNodeTree *ngroup)
792 bNode *node;
793 bNodeType *ntype= node_get_type(ntree, type, ngroup);
794 bNodeSocketType *stype;
796 node= MEM_callocN(sizeof(bNode), "new node");
797 BLI_addtail(&ntree->nodes, node);
798 node->typeinfo= ntype;
800 if(ngroup)
801 BLI_strncpy(node->name, ngroup->id.name+2, NODE_MAXSTR);
802 else
803 BLI_strncpy(node->name, ntype->name, NODE_MAXSTR);
804 node->type= ntype->type;
805 node->flag= NODE_SELECT|ntype->flag;
806 node->width= ntype->width;
807 node->miniwidth= 42.0f; /* small value only, allows print of first chars */
809 if(type==NODE_GROUP)
810 node->id= (ID *)ngroup;
812 if(ntype->inputs) {
813 stype= ntype->inputs;
814 while(stype->type != -1) {
815 node_add_socket_type(&node->inputs, stype);
816 stype++;
819 if(ntype->outputs) {
820 stype= ntype->outputs;
821 while(stype->type != -1) {
822 node_add_socket_type(&node->outputs, stype);
823 stype++;
827 /* need init handler later? */
828 /* got it-bob*/
829 if(ntype->initfunc!=NULL)
830 ntype->initfunc(node);
832 return node;
835 /* keep socket listorder identical, for copying links */
836 /* ntree is the target tree */
837 bNode *nodeCopyNode(struct bNodeTree *ntree, struct bNode *node, int internal)
839 bNode *nnode= MEM_callocN(sizeof(bNode), "dupli node");
840 bNodeSocket *sock, *oldsock;
842 *nnode= *node;
843 BLI_addtail(&ntree->nodes, nnode);
845 duplicatelist(&nnode->inputs, &node->inputs);
846 oldsock= node->inputs.first;
847 for(sock= nnode->inputs.first; sock; sock= sock->next, oldsock= oldsock->next) {
848 oldsock->new_sock= sock;
849 if(internal)
850 sock->own_index= 0;
853 duplicatelist(&nnode->outputs, &node->outputs);
854 oldsock= node->outputs.first;
855 for(sock= nnode->outputs.first; sock; sock= sock->next, oldsock= oldsock->next) {
856 if(internal)
857 sock->own_index= 0;
858 sock->stack_index= 0;
859 sock->ns.data= NULL;
860 oldsock->new_sock= sock;
863 if(nnode->id)
864 nnode->id->us++;
866 if(node->typeinfo->copystoragefunc)
867 node->typeinfo->copystoragefunc(node, nnode);
869 node->new_node= nnode;
870 nnode->new_node= NULL;
871 nnode->preview= NULL;
873 return nnode;
876 bNodeLink *nodeAddLink(bNodeTree *ntree, bNode *fromnode, bNodeSocket *fromsock, bNode *tonode, bNodeSocket *tosock)
878 bNodeLink *link= MEM_callocN(sizeof(bNodeLink), "link");
880 BLI_addtail(&ntree->links, link);
881 link->fromnode= fromnode;
882 link->fromsock= fromsock;
883 link->tonode= tonode;
884 link->tosock= tosock;
886 return link;
889 void nodeRemLink(bNodeTree *ntree, bNodeLink *link)
891 BLI_remlink(&ntree->links, link);
892 if(link->tosock)
893 link->tosock->link= NULL;
894 MEM_freeN(link);
898 bNodeTree *ntreeAddTree(int type)
900 bNodeTree *ntree= MEM_callocN(sizeof(bNodeTree), "new node tree");
901 ntree->type= type;
902 ntree->alltypes.first = NULL;
903 ntree->alltypes.last = NULL;
905 ntreeInitTypes(ntree);
906 return ntree;
909 bNodeTree *ntreeCopyTree(bNodeTree *ntree, int internal_select)
911 bNodeTree *newtree;
912 bNode *node, *nnode, *last;
913 bNodeLink *link, *nlink;
914 bNodeSocket *sock;
915 int a;
917 if(ntree==NULL) return NULL;
919 if(internal_select==0) {
920 /* is ntree part of library? */
921 for(newtree=G.main->nodetree.first; newtree; newtree= newtree->id.next)
922 if(newtree==ntree) break;
923 if(newtree)
924 newtree= copy_libblock(ntree);
925 else
926 newtree= MEM_dupallocN(ntree);
927 newtree->nodes.first= newtree->nodes.last= NULL;
928 newtree->links.first= newtree->links.last= NULL;
930 else
931 newtree= ntree;
933 last= ntree->nodes.last;
934 for(node= ntree->nodes.first; node; node= node->next) {
936 node->new_node= NULL;
937 if(internal_select==0 || (node->flag & NODE_SELECT)) {
938 nnode= nodeCopyNode(newtree, node, internal_select); /* sets node->new */
939 if(internal_select) {
940 node->flag &= ~NODE_SELECT;
941 nnode->flag |= NODE_SELECT;
943 node->flag &= ~NODE_ACTIVE;
945 /* deselect original sockets */
946 for(sock= node->inputs.first; sock; sock= sock->next) {
947 if(sock->flag & SOCK_SEL) sock->flag&= ~SOCK_SEL;
949 for(sock= node->outputs.first; sock; sock= sock->next) {
950 if(sock->flag & SOCK_SEL) sock->flag&= ~SOCK_SEL;
953 /* set tree selin and selout to new sockets */
954 for(sock= nnode->inputs.first; sock; sock= sock->next) {
955 if(sock->flag & SOCK_SEL) {
956 ntree->selin= sock;
957 break;
960 for(sock= nnode->outputs.first; sock; sock= sock->next) {
961 if(sock->flag & SOCK_SEL) {
962 ntree->selout= sock;
963 break;
967 if(node==last) break;
970 /* check for copying links */
971 for(link= ntree->links.first; link; link= link->next) {
972 if(link->fromnode->new_node && link->tonode->new_node) {
973 nlink= nodeAddLink(newtree, link->fromnode->new_node, NULL, link->tonode->new_node, NULL);
974 /* sockets were copied in order */
975 for(a=0, sock= link->fromnode->outputs.first; sock; sock= sock->next, a++) {
976 if(sock==link->fromsock)
977 break;
979 nlink->fromsock= BLI_findlink(&link->fromnode->new_node->outputs, a);
981 for(a=0, sock= link->tonode->inputs.first; sock; sock= sock->next, a++) {
982 if(sock==link->tosock)
983 break;
985 nlink->tosock= BLI_findlink(&link->tonode->new_node->inputs, a);
989 /* own type definition for group usage */
990 if(internal_select==0) {
991 if(ntree->owntype) {
992 newtree->owntype= MEM_dupallocN(ntree->owntype);
993 if(ntree->owntype->inputs)
994 newtree->owntype->inputs= MEM_dupallocN(ntree->owntype->inputs);
995 if(ntree->owntype->outputs)
996 newtree->owntype->outputs= MEM_dupallocN(ntree->owntype->outputs);
999 /* weird this is required... there seem to be link pointers wrong still? */
1000 /* anyhoo, doing this solves crashes on copying entire tree (copy scene) and delete nodes */
1001 ntreeSolveOrder(newtree);
1003 return newtree;
1006 /* ************** Free stuff ********** */
1008 /* goes over entire tree */
1009 void nodeUnlinkNode(bNodeTree *ntree, bNode *node)
1011 bNodeLink *link, *next;
1012 bNodeSocket *sock;
1013 ListBase *lb;
1015 for(link= ntree->links.first; link; link= next) {
1016 next= link->next;
1018 if(link->fromnode==node) {
1019 lb= &node->outputs;
1020 NodeTagChanged(ntree, link->tonode);
1022 else if(link->tonode==node)
1023 lb= &node->inputs;
1024 else
1025 lb= NULL;
1027 if(lb) {
1028 for(sock= lb->first; sock; sock= sock->next) {
1029 if(link->fromsock==sock || link->tosock==sock)
1030 break;
1032 if(sock) {
1033 nodeRemLink(ntree, link);
1039 static void composit_free_node_cache(bNode *node)
1041 bNodeSocket *sock;
1043 for(sock= node->outputs.first; sock; sock= sock->next) {
1044 if(sock->ns.data) {
1045 free_compbuf(sock->ns.data);
1046 sock->ns.data= NULL;
1051 void nodeFreeNode(bNodeTree *ntree, bNode *node)
1053 nodeUnlinkNode(ntree, node);
1054 BLI_remlink(&ntree->nodes, node);
1056 /* since it is called while free database, node->id is undefined */
1058 if(ntree->type==NTREE_COMPOSIT)
1059 composit_free_node_cache(node);
1060 BLI_freelistN(&node->inputs);
1061 BLI_freelistN(&node->outputs);
1063 if(node->preview) {
1064 if(node->preview->rect)
1065 MEM_freeN(node->preview->rect);
1066 MEM_freeN(node->preview);
1068 if(node->typeinfo && node->typeinfo->freestoragefunc) {
1069 node->typeinfo->freestoragefunc(node);
1071 MEM_freeN(node);
1074 /* do not free ntree itself here, free_libblock calls this function too */
1075 void ntreeFreeTree(bNodeTree *ntree)
1077 bNode *node, *next;
1079 if(ntree==NULL) return;
1081 ntreeEndExecTree(ntree); /* checks for if it is still initialized */
1083 BLI_freelistN(&ntree->links); /* do first, then unlink_node goes fast */
1085 for(node= ntree->nodes.first; node; node= next) {
1086 next= node->next;
1087 nodeFreeNode(ntree, node);
1090 if(ntree->owntype) {
1091 if(ntree->owntype->inputs)
1092 MEM_freeN(ntree->owntype->inputs);
1093 if(ntree->owntype->outputs)
1094 MEM_freeN(ntree->owntype->outputs);
1095 MEM_freeN(ntree->owntype);
1099 void ntreeFreeCache(bNodeTree *ntree)
1101 bNode *node;
1103 if(ntree==NULL) return;
1105 if(ntree->type==NTREE_COMPOSIT)
1106 for(node= ntree->nodes.first; node; node= node->next)
1107 composit_free_node_cache(node);
1111 void ntreeMakeLocal(bNodeTree *ntree)
1113 int local=0, lib=0;
1115 /* - only lib users: do nothing
1116 * - only local users: set flag
1117 * - mixed: make copy
1120 if(ntree->id.lib==NULL) return;
1121 if(ntree->id.us==1) {
1122 ntree->id.lib= 0;
1123 ntree->id.flag= LIB_LOCAL;
1124 new_id(0, (ID *)ntree, 0);
1125 return;
1128 /* now check users of groups... again typedepending, callback... */
1129 if(ntree->type==NTREE_SHADER) {
1130 Material *ma;
1131 for(ma= G.main->mat.first; ma; ma= ma->id.next) {
1132 if(ma->nodetree) {
1133 bNode *node;
1135 /* find if group is in tree */
1136 for(node= ma->nodetree->nodes.first; node; node= node->next) {
1137 if(node->id == (ID *)ntree) {
1138 if(ma->id.lib) lib= 1;
1139 else local= 1;
1145 else if(ntree->type==NTREE_COMPOSIT) {
1146 Scene *sce;
1147 for(sce= G.main->scene.first; sce; sce= sce->id.next) {
1148 if(sce->nodetree) {
1149 bNode *node;
1151 /* find if group is in tree */
1152 for(node= sce->nodetree->nodes.first; node; node= node->next) {
1153 if(node->id == (ID *)ntree) {
1154 if(sce->id.lib) lib= 1;
1155 else local= 1;
1162 /* if all users are local, we simply make tree local */
1163 if(local && lib==0) {
1164 ntree->id.lib= NULL;
1165 ntree->id.flag= LIB_LOCAL;
1166 new_id(0, (ID *)ntree, 0);
1168 else if(local && lib) {
1169 /* this is the mixed case, we copy the tree and assign it to local users */
1170 bNodeTree *newtree= ntreeCopyTree(ntree, 0);
1172 newtree->id.us= 0;
1174 if(ntree->type==NTREE_SHADER) {
1175 Material *ma;
1176 for(ma= G.main->mat.first; ma; ma= ma->id.next) {
1177 if(ma->nodetree) {
1178 bNode *node;
1180 /* find if group is in tree */
1181 for(node= ma->nodetree->nodes.first; node; node= node->next) {
1182 if(node->id == (ID *)ntree) {
1183 if(ma->id.lib==NULL) {
1184 node->id= &newtree->id;
1185 newtree->id.us++;
1186 ntree->id.us--;
1193 else if(ntree->type==NTREE_COMPOSIT) {
1194 Scene *sce;
1195 for(sce= G.main->scene.first; sce; sce= sce->id.next) {
1196 if(sce->nodetree) {
1197 bNode *node;
1199 /* find if group is in tree */
1200 for(node= sce->nodetree->nodes.first; node; node= node->next) {
1201 if(node->id == (ID *)ntree) {
1202 if(sce->id.lib==NULL) {
1203 node->id= &newtree->id;
1204 newtree->id.us++;
1205 ntree->id.us--;
1216 /* ************ find stuff *************** */
1218 static int ntreeHasType(bNodeTree *ntree, int type)
1220 bNode *node;
1222 if(ntree)
1223 for(node= ntree->nodes.first; node; node= node->next)
1224 if(node->type == type)
1225 return 1;
1226 return 0;
1229 bNodeLink *nodeFindLink(bNodeTree *ntree, bNodeSocket *from, bNodeSocket *to)
1231 bNodeLink *link;
1233 for(link= ntree->links.first; link; link= link->next) {
1234 if(link->fromsock==from && link->tosock==to)
1235 return link;
1236 if(link->fromsock==to && link->tosock==from) /* hrms? */
1237 return link;
1239 return NULL;
1242 int nodeCountSocketLinks(bNodeTree *ntree, bNodeSocket *sock)
1244 bNodeLink *link;
1245 int tot= 0;
1247 for(link= ntree->links.first; link; link= link->next) {
1248 if(link->fromsock==sock || link->tosock==sock)
1249 tot++;
1251 return tot;
1254 bNode *nodeGetActive(bNodeTree *ntree)
1256 bNode *node;
1258 if(ntree==NULL) return NULL;
1260 for(node= ntree->nodes.first; node; node= node->next)
1261 if(node->flag & NODE_ACTIVE)
1262 break;
1263 return node;
1266 /* two active flags, ID nodes have special flag for buttons display */
1267 bNode *nodeGetActiveID(bNodeTree *ntree, short idtype)
1269 bNode *node;
1271 if(ntree==NULL) return NULL;
1273 /* check for group edit */
1274 for(node= ntree->nodes.first; node; node= node->next)
1275 if(node->flag & NODE_GROUP_EDIT)
1276 break;
1278 if(node)
1279 ntree= (bNodeTree*)node->id;
1281 /* now find active node with this id */
1282 for(node= ntree->nodes.first; node; node= node->next)
1283 if(node->id && GS(node->id->name)==idtype)
1284 if(node->flag & NODE_ACTIVE_ID)
1285 break;
1287 return node;
1290 /* two active flags, ID nodes have special flag for buttons display */
1291 void nodeClearActiveID(bNodeTree *ntree, short idtype)
1293 bNode *node;
1295 if(ntree==NULL) return;
1297 for(node= ntree->nodes.first; node; node= node->next)
1298 if(node->id && GS(node->id->name)==idtype)
1299 node->flag &= ~NODE_ACTIVE_ID;
1302 /* two active flags, ID nodes have special flag for buttons display */
1303 void nodeSetActive(bNodeTree *ntree, bNode *node)
1305 bNode *tnode;
1307 /* make sure only one node is active, and only one per ID type */
1308 for(tnode= ntree->nodes.first; tnode; tnode= tnode->next) {
1309 tnode->flag &= ~NODE_ACTIVE;
1311 if(node->id && tnode->id) {
1312 if(GS(node->id->name) == GS(tnode->id->name))
1313 tnode->flag &= ~NODE_ACTIVE_ID;
1317 node->flag |= NODE_ACTIVE;
1318 if(node->id)
1319 node->flag |= NODE_ACTIVE_ID;
1322 /* use flags are not persistant yet, groups might need different tagging, so we do it each time
1323 when we need to get this info */
1324 void ntreeSocketUseFlags(bNodeTree *ntree)
1326 bNode *node;
1327 bNodeSocket *sock;
1328 bNodeLink *link;
1330 /* clear flags */
1331 for(node= ntree->nodes.first; node; node= node->next) {
1332 for(sock= node->inputs.first; sock; sock= sock->next)
1333 sock->flag &= ~SOCK_IN_USE;
1334 for(sock= node->outputs.first; sock; sock= sock->next)
1335 sock->flag &= ~SOCK_IN_USE;
1338 /* tag all thats in use */
1339 for(link= ntree->links.first; link; link= link->next) {
1340 link->fromsock->flag |= SOCK_IN_USE;
1341 link->tosock->flag |= SOCK_IN_USE;
1345 /* ************** dependency stuff *********** */
1347 /* node is guaranteed to be not checked before */
1348 static int node_recurs_check(bNode *node, bNode ***nsort, int level)
1350 bNode *fromnode;
1351 bNodeSocket *sock;
1352 int has_inputlinks= 0;
1354 node->done= 1;
1355 level++;
1357 for(sock= node->inputs.first; sock; sock= sock->next) {
1358 if(sock->link) {
1359 has_inputlinks= 1;
1360 fromnode= sock->link->fromnode;
1361 if(fromnode->done==0) {
1362 fromnode->level= node_recurs_check(fromnode, nsort, level);
1366 // printf("node sort %s level %d\n", node->name, level);
1367 **nsort= node;
1368 (*nsort)++;
1370 if(has_inputlinks)
1371 return level;
1372 else
1373 return 0xFFF;
1376 void ntreeSolveOrder(bNodeTree *ntree)
1378 bNode *node, **nodesort, **nsort;
1379 bNodeSocket *sock;
1380 bNodeLink *link;
1381 int a, totnode=0;
1383 /* the solve-order is called on each tree change, so we should be sure no exec can be running */
1384 ntreeEndExecTree(ntree);
1386 /* set links pointers the input sockets, to find dependencies */
1387 /* first clear data */
1388 for(node= ntree->nodes.first; node; node= node->next) {
1389 node->done= 0;
1390 totnode++;
1391 for(sock= node->inputs.first; sock; sock= sock->next)
1392 sock->link= NULL;
1394 if(totnode==0)
1395 return;
1397 for(link= ntree->links.first; link; link= link->next) {
1398 link->tosock->link= link;
1401 nsort= nodesort= MEM_callocN(totnode*sizeof(void *), "sorted node array");
1403 /* recursive check */
1404 for(node= ntree->nodes.first; node; node= node->next) {
1405 if(node->done==0) {
1406 node->level= node_recurs_check(node, &nsort, 0);
1410 /* re-insert nodes in order, first a paranoia check */
1411 for(a=0; a<totnode; a++) {
1412 if(nodesort[a]==NULL)
1413 break;
1415 if(a<totnode)
1416 printf("sort error in node tree");
1417 else {
1418 ntree->nodes.first= ntree->nodes.last= NULL;
1419 for(a=0; a<totnode; a++)
1420 BLI_addtail(&ntree->nodes, nodesort[a]);
1423 MEM_freeN(nodesort);
1425 /* find the active outputs, might become tree type dependant handler */
1426 for(node= ntree->nodes.first; node; node= node->next) {
1427 if(node->typeinfo->nclass==NODE_CLASS_OUTPUT) {
1428 bNode *tnode;
1429 int output= 0;
1431 /* we need a check for which output node should be tagged like this, below an exception */
1432 if(node->type==CMP_NODE_OUTPUT_FILE)
1433 continue;
1435 /* there is more types having output class, each one is checked */
1436 for(tnode= ntree->nodes.first; tnode; tnode= tnode->next) {
1437 if(tnode->typeinfo->nclass==NODE_CLASS_OUTPUT) {
1438 if(tnode->type==node->type) {
1439 if(tnode->flag & NODE_DO_OUTPUT) {
1440 output++;
1441 if(output>1)
1442 tnode->flag &= ~NODE_DO_OUTPUT;
1447 if(output==0)
1448 node->flag |= NODE_DO_OUTPUT;
1452 /* here we could recursively set which nodes have to be done,
1453 might be different for editor or for "real" use... */
1456 /* should be callback! */
1457 void NodeTagChanged(bNodeTree *ntree, bNode *node)
1459 if(ntree->type==NTREE_COMPOSIT) {
1460 bNodeSocket *sock;
1462 for(sock= node->outputs.first; sock; sock= sock->next) {
1463 if(sock->ns.data) {
1464 free_compbuf(sock->ns.data);
1465 sock->ns.data= NULL;
1467 //if(node->preview && node->preview->rect) {
1468 // MEM_freeN(node->preview->rect);
1469 // node->preview->rect= NULL;
1474 node->need_exec= 1;
1478 void NodeTagIDChanged(bNodeTree *ntree, ID *id)
1480 if(id==NULL)
1481 return;
1483 if(ntree->type==NTREE_COMPOSIT) {
1484 bNode *node;
1486 for(node= ntree->nodes.first; node; node= node->next)
1487 if(node->id==id)
1488 NodeTagChanged(ntree, node);
1493 /* *************** preview *********** */
1495 /* if node->preview, then we assume the rect to exist */
1497 static void nodeInitPreview(bNode *node, int xsize, int ysize)
1500 if(node->preview==NULL) {
1501 node->preview= MEM_callocN(sizeof(bNodePreview), "node preview");
1502 // printf("added preview %s\n", node->name);
1505 /* node previews can get added with variable size this way */
1506 if(xsize==0 || ysize==0)
1507 return;
1509 /* sanity checks & initialize */
1510 if(node->preview->rect) {
1511 if(node->preview->xsize!=xsize && node->preview->ysize!=ysize) {
1512 MEM_freeN(node->preview->rect);
1513 node->preview->rect= NULL;
1517 if(node->preview->rect==NULL) {
1518 node->preview->rect= MEM_callocN(4*xsize + xsize*ysize*sizeof(float)*4, "node preview rect");
1519 node->preview->xsize= xsize;
1520 node->preview->ysize= ysize;
1524 void ntreeInitPreview(bNodeTree *ntree, int xsize, int ysize)
1526 bNode *node;
1528 if(ntree==NULL)
1529 return;
1531 for(node= ntree->nodes.first; node; node= node->next) {
1532 if(node->typeinfo->flag & NODE_PREVIEW) /* hrms, check for closed nodes? */
1533 nodeInitPreview(node, xsize, ysize);
1534 if(node->type==NODE_GROUP && (node->flag & NODE_GROUP_EDIT))
1535 ntreeInitPreview((bNodeTree *)node->id, xsize, ysize);
1539 static void nodeClearPreview(bNode *node)
1541 if(node->preview && node->preview->rect)
1542 memset(node->preview->rect, 0, MEM_allocN_len(node->preview->rect));
1545 /* use it to enforce clear */
1546 void ntreeClearPreview(bNodeTree *ntree)
1548 bNode *node;
1550 if(ntree==NULL)
1551 return;
1553 for(node= ntree->nodes.first; node; node= node->next) {
1554 if(node->typeinfo->flag & NODE_PREVIEW)
1555 nodeClearPreview(node);
1556 if(node->type==NODE_GROUP && (node->flag & NODE_GROUP_EDIT))
1557 ntreeClearPreview((bNodeTree *)node->id);
1561 /* hack warning! this function is only used for shader previews, and
1562 since it gets called multiple times per pixel for Ztransp we only
1563 add the color once. Preview gets cleared before it starts render though */
1564 void nodeAddToPreview(bNode *node, float *col, int x, int y)
1566 bNodePreview *preview= node->preview;
1567 if(preview) {
1568 if(x>=0 && y>=0) {
1569 if(x<preview->xsize && y<preview->ysize) {
1570 float *tar= preview->rect+ 4*((preview->xsize*y) + x);
1571 if(tar[0]==0.0f) {
1572 QUATCOPY(tar, col);
1575 //else printf("prv out bound x y %d %d\n", x, y);
1577 //else printf("prv out bound x y %d %d\n", x, y);
1583 /* ******************* executing ************* */
1585 /* see notes at ntreeBeginExecTree */
1586 static void group_node_get_stack(bNode *node, bNodeStack *stack, bNodeStack **in, bNodeStack **out, bNodeStack **gin, bNodeStack **gout)
1588 bNodeSocket *sock;
1590 /* build pointer stack */
1591 for(sock= node->inputs.first; sock; sock= sock->next) {
1592 if(sock->intern) {
1593 /* yep, intern can have link or is hidden socket */
1594 if(sock->link)
1595 *(in++)= stack + sock->link->fromsock->stack_index;
1596 else
1597 *(in++)= &sock->ns;
1599 else
1600 *(in++)= gin[sock->stack_index_ext];
1603 for(sock= node->outputs.first; sock; sock= sock->next) {
1604 if(sock->intern)
1605 *(out++)= stack + sock->stack_index;
1606 else
1607 *(out++)= gout[sock->stack_index_ext];
1611 static void node_group_execute(bNodeStack *stack, void *data, bNode *gnode, bNodeStack **in, bNodeStack **out)
1613 bNode *node;
1614 bNodeTree *ntree= (bNodeTree *)gnode->id;
1615 bNodeStack *nsin[MAX_SOCKET]; /* arbitrary... watch this */
1616 bNodeStack *nsout[MAX_SOCKET]; /* arbitrary... watch this */
1618 if(ntree==NULL) return;
1620 stack+= gnode->stack_index;
1622 for(node= ntree->nodes.first; node; node= node->next) {
1623 if(node->typeinfo->execfunc) {
1624 group_node_get_stack(node, stack, nsin, nsout, in, out);
1626 /* for groups, only execute outputs for edited group */
1627 if(node->typeinfo->nclass==NODE_CLASS_OUTPUT) {
1628 if(gnode->flag & NODE_GROUP_EDIT)
1629 if(node->flag & NODE_DO_OUTPUT)
1630 node->typeinfo->execfunc(data, node, nsin, nsout);
1632 else
1633 node->typeinfo->execfunc(data, node, nsin, nsout);
1637 /* free internal group output nodes */
1638 if(ntree->type==NTREE_COMPOSIT) {
1639 for(node= ntree->nodes.first; node; node= node->next) {
1640 if(node->typeinfo->execfunc) {
1641 bNodeSocket *sock;
1643 for(sock= node->outputs.first; sock; sock= sock->next) {
1644 if(sock->intern) {
1645 bNodeStack *ns= stack + sock->stack_index;
1646 if(ns->data) {
1647 free_compbuf(ns->data);
1648 ns->data= NULL;
1657 /* recursively called for groups */
1658 /* we set all trees on own local indices, but put a total counter
1659 in the groups, so each instance of a group has own stack */
1660 static int ntree_begin_exec_tree(bNodeTree *ntree)
1662 bNode *node;
1663 bNodeSocket *sock;
1664 int index= 0, index_in= 0, index_out= 0;
1666 if((ntree->init & NTREE_TYPE_INIT)==0)
1667 ntreeInitTypes(ntree);
1669 /* create indices for stack, check preview */
1670 for(node= ntree->nodes.first; node; node= node->next) {
1672 for(sock= node->inputs.first; sock; sock= sock->next) {
1673 if(sock->intern==0)
1674 sock->stack_index_ext= index_in++;
1677 for(sock= node->outputs.first; sock; sock= sock->next) {
1678 sock->stack_index= index++;
1679 if(sock->intern==0)
1680 sock->stack_index_ext= index_out++;
1683 if(node->type==NODE_GROUP) {
1684 if(node->id) {
1685 node->stack_index= index;
1686 index+= ntree_begin_exec_tree((bNodeTree *)node->id);
1691 return index;
1694 /* copy socket compbufs to stack, initialize usage of curve nodes */
1695 static void composit_begin_exec(bNodeTree *ntree, int is_group)
1697 bNode *node;
1698 bNodeSocket *sock;
1700 for(node= ntree->nodes.first; node; node= node->next) {
1702 /* initialize needed for groups */
1703 node->exec= 0;
1705 if(is_group==0) {
1706 for(sock= node->outputs.first; sock; sock= sock->next) {
1707 bNodeStack *ns= ntree->stack[0] + sock->stack_index;
1709 if(sock->ns.data) {
1710 ns->data= sock->ns.data;
1711 sock->ns.data= NULL;
1715 /* cannot initialize them while using in threads */
1716 if(ELEM3(node->type, CMP_NODE_TIME, CMP_NODE_CURVE_VEC, CMP_NODE_CURVE_RGB)) {
1717 curvemapping_initialize(node->storage);
1718 if(node->type==CMP_NODE_CURVE_RGB)
1719 curvemapping_premultiply(node->storage, 0);
1721 if(node->type==NODE_GROUP)
1722 composit_begin_exec((bNodeTree *)node->id, 1);
1727 /* copy stack compbufs to sockets */
1728 static void composit_end_exec(bNodeTree *ntree, int is_group)
1730 extern void print_compbuf(char *str, struct CompBuf *cbuf);
1731 bNode *node;
1732 bNodeStack *ns;
1733 int a;
1735 for(node= ntree->nodes.first; node; node= node->next) {
1736 if(is_group==0) {
1737 bNodeSocket *sock;
1739 for(sock= node->outputs.first; sock; sock= sock->next) {
1740 ns= ntree->stack[0] + sock->stack_index;
1741 if(ns->data) {
1742 sock->ns.data= ns->data;
1743 ns->data= NULL;
1747 if(node->type==CMP_NODE_CURVE_RGB)
1748 curvemapping_premultiply(node->storage, 1);
1750 if(node->type==NODE_GROUP)
1751 composit_end_exec((bNodeTree *)node->id, 1);
1753 node->need_exec= 0;
1756 if(is_group==0) {
1757 /* internally, group buffers are not stored */
1758 for(ns= ntree->stack[0], a=0; a<ntree->stacksize; a++, ns++) {
1759 if(ns->data) {
1760 printf("freed leftover buffer from stack\n");
1761 free_compbuf(ns->data);
1767 static void group_tag_used_outputs(bNode *gnode, bNodeStack *stack)
1769 bNodeTree *ntree= (bNodeTree *)gnode->id;
1770 bNode *node;
1772 stack+= gnode->stack_index;
1774 for(node= ntree->nodes.first; node; node= node->next) {
1775 if(node->typeinfo->execfunc) {
1776 bNodeSocket *sock;
1778 for(sock= node->inputs.first; sock; sock= sock->next) {
1779 if(sock->intern) {
1780 if(sock->link) {
1781 bNodeStack *ns= stack + sock->link->fromsock->stack_index;
1782 ns->hasoutput= 1;
1783 ns->sockettype= sock->link->fromsock->type;
1785 else
1786 sock->ns.sockettype= sock->type;
1793 /* stack indices make sure all nodes only write in allocated data, for making it thread safe */
1794 /* only root tree gets the stack, to enable instances to have own stack entries */
1795 /* only two threads now! */
1796 /* per tree (and per group) unique indices are created */
1797 /* the index_ext we need to be able to map from groups to the group-node own stack */
1799 void ntreeBeginExecTree(bNodeTree *ntree)
1801 /* let's make it sure */
1802 if(ntree->init & NTREE_EXEC_INIT)
1803 return;
1805 /* allocate the stack pointer array */
1806 ntree->stack= MEM_callocN(BLENDER_MAX_THREADS*sizeof(void *), "stack array");
1808 /* goes recursive over all groups */
1809 ntree->stacksize= ntree_begin_exec_tree(ntree);
1811 if(ntree->stacksize) {
1812 bNode *node;
1813 bNodeStack *ns;
1814 int a;
1816 /* allocate the base stack */
1817 ns=ntree->stack[0]= MEM_callocN(ntree->stacksize*sizeof(bNodeStack), "node stack");
1819 /* tag inputs, the get_stack() gives own socket stackdata if not in use */
1820 for(a=0; a<ntree->stacksize; a++, ns++) ns->hasinput= 1;
1822 /* tag used outputs, so we know when we can skip operations */
1823 for(node= ntree->nodes.first; node; node= node->next) {
1824 bNodeSocket *sock;
1825 for(sock= node->inputs.first; sock; sock= sock->next) {
1826 if(sock->link) {
1827 ns= ntree->stack[0] + sock->link->fromsock->stack_index;
1828 ns->hasoutput= 1;
1829 ns->sockettype= sock->link->fromsock->type;
1831 else
1832 sock->ns.sockettype= sock->type;
1834 if(node->type==NODE_GROUP && node->id)
1835 group_tag_used_outputs(node, ntree->stack[0]);
1838 /* composite does 1 node per thread, so no multiple stacks needed */
1839 if(ntree->type==NTREE_COMPOSIT)
1840 composit_begin_exec(ntree, 0);
1841 else {
1842 for(a=1; a<BLENDER_MAX_THREADS; a++)
1843 ntree->stack[a]= MEM_dupallocN(ntree->stack[0]);
1847 ntree->init |= NTREE_EXEC_INIT;
1850 void ntreeEndExecTree(bNodeTree *ntree)
1853 if(ntree->init & NTREE_EXEC_INIT) {
1854 int a;
1856 /* another callback candidate! */
1857 if(ntree->type==NTREE_COMPOSIT)
1858 composit_end_exec(ntree, 0);
1860 if(ntree->stack) {
1861 for(a=0; a<BLENDER_MAX_THREADS; a++)
1862 if(ntree->stack[a])
1863 MEM_freeN(ntree->stack[a]);
1865 MEM_freeN(ntree->stack);
1866 ntree->stack= NULL;
1869 ntree->init &= ~NTREE_EXEC_INIT;
1873 static void node_get_stack(bNode *node, bNodeStack *stack, bNodeStack **in, bNodeStack **out)
1875 bNodeSocket *sock;
1877 /* build pointer stack */
1878 for(sock= node->inputs.first; sock; sock= sock->next) {
1879 if(sock->link)
1880 *(in++)= stack + sock->link->fromsock->stack_index;
1881 else
1882 *(in++)= &sock->ns;
1885 for(sock= node->outputs.first; sock; sock= sock->next) {
1886 *(out++)= stack + sock->stack_index;
1890 /* nodes are presorted, so exec is in order of list */
1891 void ntreeExecTree(bNodeTree *ntree, void *callerdata, int thread)
1893 bNode *node;
1894 bNodeStack *nsin[MAX_SOCKET]; /* arbitrary... watch this */
1895 bNodeStack *nsout[MAX_SOCKET]; /* arbitrary... watch this */
1896 bNodeStack *stack;
1898 /* only when initialized */
1899 if((ntree->init & NTREE_EXEC_INIT)==0)
1900 ntreeBeginExecTree(ntree);
1902 stack= ntree->stack[thread];
1904 for(node= ntree->nodes.first; node; node= node->next) {
1905 if(node->typeinfo->execfunc) {
1906 node_get_stack(node, stack, nsin, nsout);
1907 node->typeinfo->execfunc(callerdata, node, nsin, nsout);
1909 else if(node->type==NODE_GROUP && node->id) {
1910 node_get_stack(node, stack, nsin, nsout);
1911 node_group_execute(stack, callerdata, node, nsin, nsout);
1917 /* ***************************** threaded version for execute composite nodes ************* */
1918 /* these are nodes without input, only giving values */
1919 /* or nodes with only value inputs */
1920 static int node_only_value(bNode *node)
1922 bNodeSocket *sock;
1924 if(ELEM3(node->type, CMP_NODE_TIME, CMP_NODE_VALUE, CMP_NODE_RGB))
1925 return 1;
1927 /* doing this for all node types goes wrong. memory free errors */
1928 if(node->inputs.first && node->type==CMP_NODE_MAP_VALUE) {
1929 int retval= 1;
1930 for(sock= node->inputs.first; sock; sock= sock->next) {
1931 if(sock->link)
1932 retval &= node_only_value(sock->link->fromnode);
1934 return retval;
1936 return 0;
1940 /* not changing info, for thread callback */
1941 typedef struct ThreadData {
1942 bNodeStack *stack;
1943 RenderData *rd;
1944 } ThreadData;
1946 static void *exec_composite_node(void *node_v)
1948 bNodeStack *nsin[MAX_SOCKET]; /* arbitrary... watch this */
1949 bNodeStack *nsout[MAX_SOCKET]; /* arbitrary... watch this */
1950 bNode *node= node_v;
1951 ThreadData *thd= (ThreadData *)node->new_node; /* abuse */
1953 node_get_stack(node, thd->stack, nsin, nsout);
1955 if((node->flag & NODE_MUTED) && (!node_only_value(node))) {
1956 /* viewers we execute, for feedback to user */
1957 if(ELEM(node->type, CMP_NODE_VIEWER, CMP_NODE_SPLITVIEWER))
1958 node->typeinfo->execfunc(thd->rd, node, nsin, nsout);
1959 else
1960 node_compo_pass_on(node, nsin, nsout);
1962 else if(node->typeinfo->execfunc) {
1963 node->typeinfo->execfunc(thd->rd, node, nsin, nsout);
1965 else if(node->type==NODE_GROUP && node->id) {
1966 node_group_execute(thd->stack, thd->rd, node, nsin, nsout);
1969 node->exec |= NODE_READY;
1970 return 0;
1973 /* return total of executable nodes, for timecursor */
1974 /* only compositor uses it */
1975 static int setExecutableNodes(bNodeTree *ntree, ThreadData *thd)
1977 bNodeStack *nsin[MAX_SOCKET]; /* arbitrary... watch this */
1978 bNodeStack *nsout[MAX_SOCKET]; /* arbitrary... watch this */
1979 bNode *node;
1980 bNodeSocket *sock;
1981 int totnode= 0, group_edit= 0;
1983 /* note; do not add a dependency sort here, the stack was created already */
1985 /* if we are in group edit, viewer nodes get skipped when group has viewer */
1986 for(node= ntree->nodes.first; node; node= node->next)
1987 if(node->type==NODE_GROUP && (node->flag & NODE_GROUP_EDIT))
1988 if(ntreeHasType((bNodeTree *)node->id, CMP_NODE_VIEWER))
1989 group_edit= 1;
1991 for(node= ntree->nodes.first; node; node= node->next) {
1992 int a;
1994 node_get_stack(node, thd->stack, nsin, nsout);
1996 /* test the outputs */
1997 /* skip value-only nodes (should be in type!) */
1998 if(!node_only_value(node)) {
1999 for(a=0, sock= node->outputs.first; sock; sock= sock->next, a++) {
2000 if(nsout[a]->data==NULL && nsout[a]->hasoutput) {
2001 node->need_exec= 1;
2002 break;
2007 /* test the inputs */
2008 for(a=0, sock= node->inputs.first; sock; sock= sock->next, a++) {
2009 /* skip viewer nodes in bg render or group edit */
2010 if( ELEM(node->type, CMP_NODE_VIEWER, CMP_NODE_SPLITVIEWER) && (G.background || group_edit))
2011 node->need_exec= 0;
2012 /* is sock in use? */
2013 else if(sock->link) {
2014 bNodeLink *link= sock->link;
2015 /* this is the test for a cyclic case */
2016 if(link->fromnode->level >= link->tonode->level && link->tonode->level!=0xFFF) {
2017 if(link->fromnode->need_exec) {
2018 node->need_exec= 1;
2019 break;
2022 else {
2023 node->need_exec= 0;
2024 printf("Node %s skipped, cyclic dependency\n", node->name);
2029 if(node->need_exec) {
2031 /* free output buffers */
2032 for(a=0, sock= node->outputs.first; sock; sock= sock->next, a++) {
2033 if(nsout[a]->data) {
2034 free_compbuf(nsout[a]->data);
2035 nsout[a]->data= NULL;
2038 totnode++;
2039 /* printf("node needs exec %s\n", node->name); */
2041 /* tag for getExecutableNode() */
2042 node->exec= 0;
2044 else {
2045 /* tag for getExecutableNode() */
2046 node->exec= NODE_READY|NODE_FINISHED;
2051 /* last step: set the stack values for only-value nodes */
2052 /* just does all now, compared to a full buffer exec this is nothing */
2053 if(totnode) {
2054 for(node= ntree->nodes.first; node; node= node->next) {
2055 if(node->need_exec==0 && node_only_value(node)) {
2056 if(node->typeinfo->execfunc) {
2057 node_get_stack(node, thd->stack, nsin, nsout);
2058 node->typeinfo->execfunc(thd->rd, node, nsin, nsout);
2064 return totnode;
2067 /* while executing tree, free buffers from nodes that are not needed anymore */
2068 static void freeExecutableNode(bNodeTree *ntree)
2070 /* node outputs can be freed when:
2071 - not a render result or image node
2072 - when node outputs go to nodes all being set NODE_FINISHED
2074 bNode *node;
2075 bNodeSocket *sock;
2077 /* set exec flag for finished nodes that might need freed */
2078 for(node= ntree->nodes.first; node; node= node->next) {
2079 if(node->type!=CMP_NODE_R_LAYERS)
2080 if(node->exec & NODE_FINISHED)
2081 node->exec |= NODE_FREEBUFS;
2083 /* clear this flag for input links that are not done yet */
2084 for(node= ntree->nodes.first; node; node= node->next) {
2085 if((node->exec & NODE_FINISHED)==0) {
2086 for(sock= node->inputs.first; sock; sock= sock->next)
2087 if(sock->link)
2088 sock->link->fromnode->exec &= ~NODE_FREEBUFS;
2091 /* now we can free buffers */
2092 for(node= ntree->nodes.first; node; node= node->next) {
2093 if(node->exec & NODE_FREEBUFS) {
2094 for(sock= node->outputs.first; sock; sock= sock->next) {
2095 bNodeStack *ns= ntree->stack[0] + sock->stack_index;
2096 if(ns->data) {
2097 free_compbuf(ns->data);
2098 ns->data= NULL;
2099 // printf("freed buf node %s \n", node->name);
2106 static bNode *getExecutableNode(bNodeTree *ntree)
2108 bNode *node;
2109 bNodeSocket *sock;
2111 for(node= ntree->nodes.first; node; node= node->next) {
2112 if(node->exec==0) {
2114 /* input sockets should be ready */
2115 for(sock= node->inputs.first; sock; sock= sock->next) {
2116 if(sock->link)
2117 if((sock->link->fromnode->exec & NODE_READY)==0)
2118 break;
2120 if(sock==NULL)
2121 return node;
2124 return NULL;
2128 /* optimized tree execute test for compositing */
2129 void ntreeCompositExecTree(bNodeTree *ntree, RenderData *rd, int do_preview)
2131 bNode *node;
2132 ListBase threads;
2133 ThreadData thdata;
2134 int totnode, rendering= 1;
2136 if(ntree==NULL) return;
2138 if(do_preview)
2139 ntreeInitPreview(ntree, 0, 0);
2141 ntreeBeginExecTree(ntree);
2143 /* prevent unlucky accidents */
2144 if(G.background)
2145 rd->scemode &= ~R_COMP_CROP;
2147 /* setup callerdata for thread callback */
2148 thdata.rd= rd;
2149 thdata.stack= ntree->stack[0];
2151 /* fixed seed, for example noise texture */
2152 BLI_srandom(rd->cfra);
2154 /* sets need_exec tags in nodes */
2155 totnode= setExecutableNodes(ntree, &thdata);
2157 BLI_init_threads(&threads, exec_composite_node, rd->threads);
2159 while(rendering) {
2161 if(BLI_available_threads(&threads)) {
2162 node= getExecutableNode(ntree);
2163 if(node) {
2165 if(ntree->timecursor)
2166 ntree->timecursor(totnode);
2167 if(ntree->stats_draw) {
2168 char str[64];
2169 sprintf(str, "Compositing %d %s", totnode, node->name);
2170 ntree->stats_draw(str);
2172 totnode--;
2174 node->new_node = (bNode *)&thdata;
2175 node->exec= NODE_PROCESSING;
2176 BLI_insert_thread(&threads, node);
2178 else
2179 PIL_sleep_ms(50);
2181 else
2182 PIL_sleep_ms(50);
2184 rendering= 0;
2185 /* test for ESC */
2186 if(ntree->test_break && ntree->test_break()) {
2187 for(node= ntree->nodes.first; node; node= node->next)
2188 node->exec |= NODE_READY;
2191 /* check for ready ones, and if we need to continue */
2192 for(node= ntree->nodes.first; node; node= node->next) {
2193 if(node->exec & NODE_READY) {
2194 if((node->exec & NODE_FINISHED)==0) {
2195 BLI_remove_thread(&threads, node); /* this waits for running thread to finish btw */
2196 node->exec |= NODE_FINISHED;
2198 /* freeing unused buffers */
2199 if(rd->scemode & R_COMP_FREE)
2200 freeExecutableNode(ntree);
2203 else rendering= 1;
2208 BLI_end_threads(&threads);
2210 ntreeEndExecTree(ntree);
2214 /* **************** call to switch lamploop for material node ************ */
2216 void (*node_shader_lamp_loop)(struct ShadeInput *, struct ShadeResult *);
2218 void set_node_shader_lamp_loop(void (*lamp_loop_func)(ShadeInput *, ShadeResult *))
2220 node_shader_lamp_loop= lamp_loop_func;
2223 /* clumsy checking... should do dynamic outputs once */
2224 static void force_hidden_passes(bNode *node, int passflag)
2226 bNodeSocket *sock;
2228 for(sock= node->outputs.first; sock; sock= sock->next)
2229 sock->flag &= ~SOCK_UNAVAIL;
2231 sock= BLI_findlink(&node->outputs, RRES_OUT_Z);
2232 if(!(passflag & SCE_PASS_Z)) sock->flag |= SOCK_UNAVAIL;
2233 sock= BLI_findlink(&node->outputs, RRES_OUT_NORMAL);
2234 if(!(passflag & SCE_PASS_NORMAL)) sock->flag |= SOCK_UNAVAIL;
2235 sock= BLI_findlink(&node->outputs, RRES_OUT_VEC);
2236 if(!(passflag & SCE_PASS_VECTOR)) sock->flag |= SOCK_UNAVAIL;
2237 sock= BLI_findlink(&node->outputs, RRES_OUT_UV);
2238 if(!(passflag & SCE_PASS_UV)) sock->flag |= SOCK_UNAVAIL;
2239 sock= BLI_findlink(&node->outputs, RRES_OUT_RGBA);
2240 if(!(passflag & SCE_PASS_RGBA)) sock->flag |= SOCK_UNAVAIL;
2241 sock= BLI_findlink(&node->outputs, RRES_OUT_DIFF);
2242 if(!(passflag & SCE_PASS_DIFFUSE)) sock->flag |= SOCK_UNAVAIL;
2243 sock= BLI_findlink(&node->outputs, RRES_OUT_SPEC);
2244 if(!(passflag & SCE_PASS_SPEC)) sock->flag |= SOCK_UNAVAIL;
2245 sock= BLI_findlink(&node->outputs, RRES_OUT_SHADOW);
2246 if(!(passflag & SCE_PASS_SHADOW)) sock->flag |= SOCK_UNAVAIL;
2247 sock= BLI_findlink(&node->outputs, RRES_OUT_AO);
2248 if(!(passflag & SCE_PASS_AO)) sock->flag |= SOCK_UNAVAIL;
2249 sock= BLI_findlink(&node->outputs, RRES_OUT_REFLECT);
2250 if(!(passflag & SCE_PASS_REFLECT)) sock->flag |= SOCK_UNAVAIL;
2251 sock= BLI_findlink(&node->outputs, RRES_OUT_REFRACT);
2252 if(!(passflag & SCE_PASS_REFRACT)) sock->flag |= SOCK_UNAVAIL;
2253 sock= BLI_findlink(&node->outputs, RRES_OUT_RADIO);
2254 if(!(passflag & SCE_PASS_RADIO)) sock->flag |= SOCK_UNAVAIL;
2255 sock= BLI_findlink(&node->outputs, RRES_OUT_INDEXOB);
2256 if(!(passflag & SCE_PASS_INDEXOB)) sock->flag |= SOCK_UNAVAIL;
2257 sock= BLI_findlink(&node->outputs, RRES_OUT_INDEXMAT);
2258 if(!(passflag & SCE_PASS_INDEXMAT)) sock->flag |= SOCK_UNAVAIL;
2259 sock= BLI_findlink(&node->outputs, RRES_OUT_MIST);
2260 if(!(passflag & SCE_PASS_MIST)) sock->flag |= SOCK_UNAVAIL;
2263 /* based on rules, force sockets hidden always */
2264 void ntreeCompositForceHidden(bNodeTree *ntree)
2266 bNode *node;
2268 if(ntree==NULL) return;
2270 for(node= ntree->nodes.first; node; node= node->next) {
2271 if( node->type==CMP_NODE_R_LAYERS) {
2272 Scene *sce= node->id?(Scene *)node->id:G.scene; /* G.scene is WEAK! */
2273 SceneRenderLayer *srl= BLI_findlink(&sce->r.layers, node->custom1);
2274 if(srl)
2275 force_hidden_passes(node, srl->passflag);
2277 else if( node->type==CMP_NODE_IMAGE) {
2278 Image *ima= (Image *)node->id;
2279 if(ima) {
2280 if(ima->rr) {
2281 ImageUser *iuser= node->storage;
2282 RenderLayer *rl= BLI_findlink(&ima->rr->layers, iuser->layer);
2283 if(rl)
2284 force_hidden_passes(node, rl->passflag);
2285 else
2286 force_hidden_passes(node, 0);
2288 else if(ima->type!=IMA_TYPE_MULTILAYER) { /* if ->rr not yet read we keep inputs */
2289 force_hidden_passes(node, RRES_OUT_Z);
2291 else
2292 force_hidden_passes(node, 0);
2294 else
2295 force_hidden_passes(node, 0);
2301 /* called from render pipeline, to tag render input and output */
2302 /* need to do all scenes, to prevent errors when you re-render 1 scene */
2303 void ntreeCompositTagRender(Scene *curscene)
2305 Scene *sce;
2307 for(sce= G.main->scene.first; sce; sce= sce->id.next) {
2308 if(sce->nodetree) {
2309 bNode *node;
2311 for(node= sce->nodetree->nodes.first; node; node= node->next) {
2312 if(node->id==(ID *)curscene || node->type==CMP_NODE_COMPOSITE)
2313 NodeTagChanged(sce->nodetree, node);
2319 /* tags nodes that have animation capabilities */
2320 int ntreeCompositTagAnimated(bNodeTree *ntree)
2322 bNode *node;
2323 int tagged= 0;
2325 if(ntree==NULL) return 0;
2327 for(node= ntree->nodes.first; node; node= node->next) {
2328 if(node->type==CMP_NODE_IMAGE) {
2329 Image *ima= (Image *)node->id;
2330 if(ima && ELEM(ima->source, IMA_SRC_MOVIE, IMA_SRC_SEQUENCE)) {
2331 NodeTagChanged(ntree, node);
2332 tagged= 1;
2335 else if(node->type==CMP_NODE_TIME) {
2336 NodeTagChanged(ntree, node);
2337 tagged= 1;
2339 else if(node->type==CMP_NODE_R_LAYERS) {
2340 NodeTagChanged(ntree, node);
2341 tagged= 1;
2343 else if(node->type==NODE_GROUP) {
2344 if( ntreeCompositTagAnimated((bNodeTree *)node->id) ) {
2345 NodeTagChanged(ntree, node);
2350 return tagged;
2354 /* called from image window preview */
2355 void ntreeCompositTagGenerators(bNodeTree *ntree)
2357 bNode *node;
2359 if(ntree==NULL) return;
2361 for(node= ntree->nodes.first; node; node= node->next) {
2362 if( ELEM(node->type, CMP_NODE_R_LAYERS, CMP_NODE_IMAGE))
2363 NodeTagChanged(ntree, node);
2367 /* ************* node definition init ********** */
2369 static bNodeType *is_nodetype_registered(ListBase *typelist, int type)
2371 bNodeType *ntype= typelist->first;
2373 for(;ntype; ntype= ntype->next )
2374 if(ntype->type==type)
2375 return ntype;
2377 return NULL;
2380 /* type can be from a static array, we make copy for duplicate types (like group) */
2381 void nodeRegisterType(ListBase *typelist, const bNodeType *ntype)
2383 bNodeType *found= is_nodetype_registered(typelist, ntype->type);
2385 if(found==NULL) {
2386 bNodeType *ntypen= MEM_mallocN(sizeof(bNodeType), "node type");
2387 *ntypen= *ntype;
2388 BLI_addtail(typelist, ntypen);
2392 static void registerCompositNodes(ListBase *ntypelist)
2394 nodeRegisterType(ntypelist, &node_group_typeinfo);
2395 nodeRegisterType(ntypelist, &cmp_node_rlayers);
2396 nodeRegisterType(ntypelist, &cmp_node_image);
2397 nodeRegisterType(ntypelist, &cmp_node_texture);
2398 nodeRegisterType(ntypelist, &cmp_node_value);
2399 nodeRegisterType(ntypelist, &cmp_node_rgb);
2400 nodeRegisterType(ntypelist, &cmp_node_curve_time);
2402 nodeRegisterType(ntypelist, &cmp_node_composite);
2403 nodeRegisterType(ntypelist, &cmp_node_viewer);
2404 nodeRegisterType(ntypelist, &cmp_node_splitviewer);
2405 nodeRegisterType(ntypelist, &cmp_node_output_file);
2407 nodeRegisterType(ntypelist, &cmp_node_curve_rgb);
2408 nodeRegisterType(ntypelist, &cmp_node_mix_rgb);
2409 nodeRegisterType(ntypelist, &cmp_node_hue_sat);
2410 nodeRegisterType(ntypelist, &cmp_node_alphaover);
2411 nodeRegisterType(ntypelist, &cmp_node_zcombine);
2413 nodeRegisterType(ntypelist, &cmp_node_normal);
2414 nodeRegisterType(ntypelist, &cmp_node_curve_vec);
2415 nodeRegisterType(ntypelist, &cmp_node_map_value);
2416 nodeRegisterType(ntypelist, &cmp_node_normalize);
2418 nodeRegisterType(ntypelist, &cmp_node_filter);
2419 nodeRegisterType(ntypelist, &cmp_node_blur);
2420 nodeRegisterType(ntypelist, &cmp_node_vecblur);
2421 nodeRegisterType(ntypelist, &cmp_node_dilateerode);
2422 nodeRegisterType(ntypelist, &cmp_node_defocus);
2423 nodeRegisterType(ntypelist, &cmp_node_normal_map);
2425 nodeRegisterType(ntypelist, &cmp_node_valtorgb);
2426 nodeRegisterType(ntypelist, &cmp_node_rgbtobw);
2427 nodeRegisterType(ntypelist, &cmp_node_setalpha);
2428 nodeRegisterType(ntypelist, &cmp_node_idmask);
2429 nodeRegisterType(ntypelist, &cmp_node_math);
2430 nodeRegisterType(ntypelist, &cmp_node_seprgba);
2431 nodeRegisterType(ntypelist, &cmp_node_combrgba);
2432 nodeRegisterType(ntypelist, &cmp_node_sephsva);
2433 nodeRegisterType(ntypelist, &cmp_node_combhsva);
2434 nodeRegisterType(ntypelist, &cmp_node_sepyuva);
2435 nodeRegisterType(ntypelist, &cmp_node_combyuva);
2436 nodeRegisterType(ntypelist, &cmp_node_sepycca);
2437 nodeRegisterType(ntypelist, &cmp_node_combycca);
2438 nodeRegisterType(ntypelist, &cmp_node_premulkey);
2440 nodeRegisterType(ntypelist, &cmp_node_diff_matte);
2441 nodeRegisterType(ntypelist, &cmp_node_chroma);
2442 nodeRegisterType(ntypelist, &cmp_node_channel_matte);
2443 nodeRegisterType(ntypelist, &cmp_node_color_spill);
2444 nodeRegisterType(ntypelist, &cmp_node_luma_matte);
2446 nodeRegisterType(ntypelist, &cmp_node_translate);
2447 nodeRegisterType(ntypelist, &cmp_node_rotate);
2448 nodeRegisterType(ntypelist, &cmp_node_scale);
2449 nodeRegisterType(ntypelist, &cmp_node_flip);
2450 nodeRegisterType(ntypelist, &cmp_node_crop);
2451 nodeRegisterType(ntypelist, &cmp_node_displace);
2452 nodeRegisterType(ntypelist, &cmp_node_mapuv);
2454 nodeRegisterType(ntypelist, &cmp_node_circularblur);
2455 nodeRegisterType(ntypelist, &cmp_node_brightcontrast);
2456 nodeRegisterType(ntypelist, &cmp_node_gain);
2457 nodeRegisterType(ntypelist, &cmp_node_gamma);
2458 nodeRegisterType(ntypelist, &cmp_node_radialblur);
2459 nodeRegisterType(ntypelist, &cmp_node_random_value);
2460 nodeRegisterType(ntypelist, &cmp_node_boolean);
2461 nodeRegisterType(ntypelist, &cmp_node_frame_info);
2462 nodeRegisterType(ntypelist, &cmp_node_threshold);
2463 nodeRegisterType(ntypelist, &cmp_node_empty);
2464 nodeRegisterType(ntypelist, &cmp_node_directionalblur);
2465 nodeRegisterType(ntypelist, &cmp_node_invert);
2466 nodeRegisterType(ntypelist, &cmp_node_fix);
2467 nodeRegisterType(ntypelist, &cmp_node_glare);
2468 nodeRegisterType(ntypelist, &cmp_node_tonemap);
2469 nodeRegisterType(ntypelist, &cmp_node_lensdist);
2470 nodeRegisterType(ntypelist, &cmp_node_fgblur);
2473 static void registerShaderNodes(ListBase *ntypelist)
2475 nodeRegisterType(ntypelist, &node_group_typeinfo);
2476 nodeRegisterType(ntypelist, &sh_node_output);
2477 nodeRegisterType(ntypelist, &sh_node_mix_rgb);
2478 nodeRegisterType(ntypelist, &sh_node_valtorgb);
2479 nodeRegisterType(ntypelist, &sh_node_rgbtobw);
2480 nodeRegisterType(ntypelist, &sh_node_normal);
2481 nodeRegisterType(ntypelist, &sh_node_geom);
2482 nodeRegisterType(ntypelist, &sh_node_mapping);
2483 nodeRegisterType(ntypelist, &sh_node_curve_vec);
2484 nodeRegisterType(ntypelist, &sh_node_curve_rgb);
2485 nodeRegisterType(ntypelist, &sh_node_math);
2486 nodeRegisterType(ntypelist, &sh_node_vect_math);
2487 nodeRegisterType(ntypelist, &sh_node_squeeze);
2488 nodeRegisterType(ntypelist, &sh_node_camera);
2489 nodeRegisterType(ntypelist, &sh_node_material);
2490 nodeRegisterType(ntypelist, &sh_node_material_ext);
2491 nodeRegisterType(ntypelist, &sh_node_value);
2492 nodeRegisterType(ntypelist, &sh_node_rgb);
2493 nodeRegisterType(ntypelist, &sh_node_texture);
2494 nodeRegisterType(ntypelist, &sh_node_boolean);
2495 nodeRegisterType(ntypelist, &sh_node_invert);
2496 nodeRegisterType(ntypelist, &sh_node_seprgb);
2497 nodeRegisterType(ntypelist, &sh_node_combrgb);
2498 nodeRegisterType(ntypelist, &sh_node_hue_sat);
2501 void init_nodesystem(void)
2503 registerCompositNodes(&node_all_composit);
2504 registerShaderNodes(&node_all_shaders);
2507 void free_nodesystem(void)
2509 BLI_freelistN(&node_all_composit);
2510 BLI_freelistN(&node_all_shaders);