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 *****
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"
46 #include "BKE_texture.h"
47 #include "BKE_utildefines.h"
49 #include "BLI_arithb.h"
50 #include "BLI_blenlib.h"
52 #include "BLI_threads.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() */
64 #include "intern/CMP_util.h" /* stupid include path... */
68 /* not very important, but the stack solver likes to know a maximum */
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
;
86 bNodeType
*ntype
= ntree
->alltypes
.first
;
87 for(; ntype
; ntype
= ntype
->next
)
95 void ntreeInitTypes(bNodeTree
*ntree
)
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
;
104 ntree
->alltypes
= empty_list
;
105 printf("Error: no type definitions for nodes\n");
108 for(node
= ntree
->nodes
.first
; node
; 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
;
141 BLI_addtail(lb
, 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
) {
152 if(link
->fromsock
==sock
|| link
->tosock
==sock
) {
153 nodeRemLink(ntree
, link
);
157 BLI_remlink(lb
, sock
);
161 static bNodeSocket
*verify_socket(ListBase
*lb
, bNodeSocketType
*stype
)
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)
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
);
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
) {
195 node_rem_socket(ntree
, lb
, lb
->first
);
198 /* step by step compare */
200 while(stype
->type
!= -1) {
201 stype
->sock
= verify_socket(lb
, stype
);
204 /* leftovers are removed */
206 node_rem_socket(ntree
, lb
, lb
->first
);
207 /* and we put back the verified sockets */
209 while(stype
->type
!= -1) {
210 BLI_addtail(lb
, stype
->sock
);
216 void nodeVerifyType(bNodeTree
*ntree
, bNode
*node
)
218 bNodeType
*ntype
= node
->typeinfo
;
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
)
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
,
247 /* width+range */ 120, 60, 200,
248 /* class+opts */ NODE_CLASS_GROUP
, NODE_OPTIONS
,
249 /* input sock */ NULL
,
250 /* output sock */ NULL
,
255 /* freestoragefunc */ NULL
,
256 /* copystoragefunc */ NULL
,
260 /* tag internal sockets */
261 static void group_tag_internal_sockets(bNodeTree
*ngroup
)
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
);
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
)
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
)
292 for(sock
= node
->outputs
.first
; sock
; sock
= sock
->next
)
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
)
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
)
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
);
331 for(node
= ngroup
->nodes
.first
; node
; node
= node
->next
) {
332 if(node
->type
==NODE_GROUP
)
334 for(sock
= node
->inputs
.first
; sock
; sock
= sock
->next
)
337 for(sock
= node
->outputs
.first
; sock
; sock
= sock
->next
)
341 /* debug: nodetrees in nodetrees not handled yet */
343 printf("group in group, not supported yet\n");
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 */
362 bNodeSocketType
*stype
;
363 bNodeSocketType
*inputs
= MEM_callocN(sizeof(bNodeSocketType
)*(totin
+1), "bNodeSocketType");
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
);
375 inputs
[a
].own_index
= sock
->own_index
;
376 inputs
[a
].internsock
= sock
;
381 inputs
[a
].type
= -1; /* terminator code */
382 ngroup
->owntype
->inputs
= inputs
;
385 /* output type arrays */
387 bNodeSocketType
*stype
;
388 bNodeSocketType
*outputs
= MEM_callocN(sizeof(bNodeSocketType
)*(totout
+1), "bNodeSocketType");
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
);
400 outputs
[a
].own_index
= sock
->own_index
;
401 outputs
[a
].internsock
= sock
;
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
)
418 for(sock
= gnode
->inputs
.first
; sock
; sock
= sock
->next
)
419 if(sock
->to_index
==index
)
424 static bNodeSocket
*groupnode_find_fromsock(bNode
*gnode
, int index
)
428 for(sock
= gnode
->outputs
.first
; sock
; sock
= sock
->next
)
429 if(sock
->to_index
==index
)
434 bNode
*nodeMakeGroupFromSelected(bNodeTree
*ntree
)
436 bNodeLink
*link
, *linkn
;
437 bNode
*node
, *gnode
, *nextn
;
440 float min
[2], max
[2];
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
)
451 DO_MINMAX2( (&node
->locx
), min
, max
);
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)
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
) {
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
) {
496 for(sock
= node
->outputs
.first
; sock
; sock
= sock
->next
) {
497 if(sock
->flag
& SOCK_SEL
) {
498 ngroup
->selout
= sock
;
505 /* move links over */
506 for(link
= ntree
->links
.first
; link
; link
= linkn
) {
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
) {
526 if(link
->tonode
->flag
& NODE_SELECT
) {
528 sock
= groupnode_find_tosock(gnode
, link
->tosock
->own_index
);
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
);
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
);
552 QUATCOPY(nsock
->ns
.vec
, sock
->ns
.vec
);
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
) {
572 for(ma
= G
.main
->mat
.first
; ma
; ma
= ma
->id
.next
) {
576 /* find if group is in tree */
577 for(node
= ma
->nodetree
->nodes
.first
; node
; node
= node
->next
)
578 if(node
->id
== (ID
*)ngroup
)
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
) {
594 for(sce
= G
.main
->scene
.first
; sce
; sce
= sce
->id
.next
) {
598 /* find if group is in tree */
599 for(node
= sce
->nodetree
->nodes
.first
; node
; node
= node
->next
)
600 if(node
->id
== (ID
*)ngroup
)
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
)
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
) {
634 for(ma
= G
.main
->mat
.first
; ma
; ma
= ma
->id
.next
) {
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
)
641 sock
->tosock
->flag
|= SOCK_IN_USE
;
642 for(sock
= node
->outputs
.first
; sock
; sock
= sock
->next
)
643 if(nodeCountSocketLinks(ma
->nodetree
, sock
))
645 sock
->tosock
->flag
|= SOCK_IN_USE
;
651 else if(ngroup
->type
==NTREE_COMPOSIT
) {
653 for(sce
= G
.main
->scene
.first
; sce
; sce
= sce
->id
.next
) {
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
)
660 sock
->tosock
->flag
|= SOCK_IN_USE
;
661 for(sock
= node
->outputs
.first
; sock
; sock
= sock
->next
)
662 if(nodeCountSocketLinks(sce
->nodetree
, sock
))
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
)
679 for(node
= ntree
->nodes
.first
; node
; node
= node
->next
) {
680 for(index
=0, tsock
= node
->inputs
.first
; tsock
; tsock
= tsock
->next
, index
++)
685 for(index
=0, tsock
= node
->outputs
.first
; tsock
; tsock
= tsock
->next
, index
++)
694 if(sockindex
) *sockindex
= index
;
702 /* returns 1 if its OK */
703 int nodeGroupUnGroup(bNodeTree
*ntree
, bNode
*gnode
)
705 bNodeLink
*link
, *linkn
;
707 bNodeTree
*ngroup
, *wgroup
;
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
) {
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
) {
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");
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");
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
);
771 void nodeCopyGroup(bNode
*gnode
)
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
)
781 sock
->tosock
= sock
->tosock
->new_sock
;
783 for(sock
=gnode
->outputs
.first
; sock
; sock
=sock
->next
)
785 sock
->tosock
= sock
->tosock
->new_sock
;
788 /* ************** Add stuff ********** */
790 bNode
*nodeAddNodeType(bNodeTree
*ntree
, int type
, bNodeTree
*ngroup
)
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
;
801 BLI_strncpy(node
->name
, ngroup
->id
.name
+2, NODE_MAXSTR
);
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 */
810 node
->id
= (ID
*)ngroup
;
813 stype
= ntype
->inputs
;
814 while(stype
->type
!= -1) {
815 node_add_socket_type(&node
->inputs
, stype
);
820 stype
= ntype
->outputs
;
821 while(stype
->type
!= -1) {
822 node_add_socket_type(&node
->outputs
, stype
);
827 /* need init handler later? */
829 if(ntype
->initfunc
!=NULL
)
830 ntype
->initfunc(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
;
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
;
853 duplicatelist(&nnode
->outputs
, &node
->outputs
);
854 oldsock
= node
->outputs
.first
;
855 for(sock
= nnode
->outputs
.first
; sock
; sock
= sock
->next
, oldsock
= oldsock
->next
) {
858 sock
->stack_index
= 0;
860 oldsock
->new_sock
= sock
;
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
;
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
;
889 void nodeRemLink(bNodeTree
*ntree
, bNodeLink
*link
)
891 BLI_remlink(&ntree
->links
, link
);
893 link
->tosock
->link
= NULL
;
898 bNodeTree
*ntreeAddTree(int type
)
900 bNodeTree
*ntree
= MEM_callocN(sizeof(bNodeTree
), "new node tree");
902 ntree
->alltypes
.first
= NULL
;
903 ntree
->alltypes
.last
= NULL
;
905 ntreeInitTypes(ntree
);
909 bNodeTree
*ntreeCopyTree(bNodeTree
*ntree
, int internal_select
)
912 bNode
*node
, *nnode
, *last
;
913 bNodeLink
*link
, *nlink
;
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;
924 newtree
= copy_libblock(ntree
);
926 newtree
= MEM_dupallocN(ntree
);
927 newtree
->nodes
.first
= newtree
->nodes
.last
= NULL
;
928 newtree
->links
.first
= newtree
->links
.last
= NULL
;
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
) {
960 for(sock
= nnode
->outputs
.first
; sock
; sock
= sock
->next
) {
961 if(sock
->flag
& SOCK_SEL
) {
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
)
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
)
985 nlink
->tosock
= BLI_findlink(&link
->tonode
->new_node
->inputs
, a
);
989 /* own type definition for group usage */
990 if(internal_select
==0) {
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
);
1006 /* ************** Free stuff ********** */
1008 /* goes over entire tree */
1009 void nodeUnlinkNode(bNodeTree
*ntree
, bNode
*node
)
1011 bNodeLink
*link
, *next
;
1015 for(link
= ntree
->links
.first
; link
; link
= next
) {
1018 if(link
->fromnode
==node
) {
1020 NodeTagChanged(ntree
, link
->tonode
);
1022 else if(link
->tonode
==node
)
1028 for(sock
= lb
->first
; sock
; sock
= sock
->next
) {
1029 if(link
->fromsock
==sock
|| link
->tosock
==sock
)
1033 nodeRemLink(ntree
, link
);
1039 static void composit_free_node_cache(bNode
*node
)
1043 for(sock
= node
->outputs
.first
; sock
; sock
= sock
->next
) {
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
);
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
);
1074 /* do not free ntree itself here, free_libblock calls this function too */
1075 void ntreeFreeTree(bNodeTree
*ntree
)
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
) {
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
)
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
)
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) {
1123 ntree
->id
.flag
= LIB_LOCAL
;
1124 new_id(0, (ID
*)ntree
, 0);
1128 /* now check users of groups... again typedepending, callback... */
1129 if(ntree
->type
==NTREE_SHADER
) {
1131 for(ma
= G
.main
->mat
.first
; ma
; ma
= ma
->id
.next
) {
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;
1145 else if(ntree
->type
==NTREE_COMPOSIT
) {
1147 for(sce
= G
.main
->scene
.first
; sce
; sce
= sce
->id
.next
) {
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;
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);
1174 if(ntree
->type
==NTREE_SHADER
) {
1176 for(ma
= G
.main
->mat
.first
; ma
; ma
= ma
->id
.next
) {
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
;
1193 else if(ntree
->type
==NTREE_COMPOSIT
) {
1195 for(sce
= G
.main
->scene
.first
; sce
; sce
= sce
->id
.next
) {
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
;
1216 /* ************ find stuff *************** */
1218 static int ntreeHasType(bNodeTree
*ntree
, int type
)
1223 for(node
= ntree
->nodes
.first
; node
; node
= node
->next
)
1224 if(node
->type
== type
)
1229 bNodeLink
*nodeFindLink(bNodeTree
*ntree
, bNodeSocket
*from
, bNodeSocket
*to
)
1233 for(link
= ntree
->links
.first
; link
; link
= link
->next
) {
1234 if(link
->fromsock
==from
&& link
->tosock
==to
)
1236 if(link
->fromsock
==to
&& link
->tosock
==from
) /* hrms? */
1242 int nodeCountSocketLinks(bNodeTree
*ntree
, bNodeSocket
*sock
)
1247 for(link
= ntree
->links
.first
; link
; link
= link
->next
) {
1248 if(link
->fromsock
==sock
|| link
->tosock
==sock
)
1254 bNode
*nodeGetActive(bNodeTree
*ntree
)
1258 if(ntree
==NULL
) return NULL
;
1260 for(node
= ntree
->nodes
.first
; node
; node
= node
->next
)
1261 if(node
->flag
& NODE_ACTIVE
)
1266 /* two active flags, ID nodes have special flag for buttons display */
1267 bNode
*nodeGetActiveID(bNodeTree
*ntree
, short idtype
)
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
)
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
)
1290 /* two active flags, ID nodes have special flag for buttons display */
1291 void nodeClearActiveID(bNodeTree
*ntree
, short idtype
)
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
)
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
;
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
)
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
)
1352 int has_inputlinks
= 0;
1357 for(sock
= node
->inputs
.first
; sock
; sock
= sock
->next
) {
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);
1376 void ntreeSolveOrder(bNodeTree
*ntree
)
1378 bNode
*node
, **nodesort
, **nsort
;
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
) {
1391 for(sock
= node
->inputs
.first
; sock
; sock
= sock
->next
)
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
) {
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
)
1416 printf("sort error in node tree");
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
) {
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
)
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
) {
1442 tnode
->flag
&= ~NODE_DO_OUTPUT
;
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
) {
1462 for(sock
= node
->outputs
.first
; sock
; sock
= sock
->next
) {
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;
1478 void NodeTagIDChanged(bNodeTree
*ntree
, ID
*id
)
1483 if(ntree
->type
==NTREE_COMPOSIT
) {
1486 for(node
= ntree
->nodes
.first
; node
; node
= node
->next
)
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)
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
)
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
)
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
;
1569 if(x
<preview
->xsize
&& y
<preview
->ysize
) {
1570 float *tar
= preview
->rect
+ 4*((preview
->xsize
*y
) + x
);
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
)
1590 /* build pointer stack */
1591 for(sock
= node
->inputs
.first
; sock
; sock
= sock
->next
) {
1593 /* yep, intern can have link or is hidden socket */
1595 *(in
++)= stack
+ sock
->link
->fromsock
->stack_index
;
1600 *(in
++)= gin
[sock
->stack_index_ext
];
1603 for(sock
= node
->outputs
.first
; sock
; sock
= sock
->next
) {
1605 *(out
++)= stack
+ sock
->stack_index
;
1607 *(out
++)= gout
[sock
->stack_index_ext
];
1611 static void node_group_execute(bNodeStack
*stack
, void *data
, bNode
*gnode
, bNodeStack
**in
, bNodeStack
**out
)
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
);
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
) {
1643 for(sock
= node
->outputs
.first
; sock
; sock
= sock
->next
) {
1645 bNodeStack
*ns
= stack
+ sock
->stack_index
;
1647 free_compbuf(ns
->data
);
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
)
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
) {
1674 sock
->stack_index_ext
= index_in
++;
1677 for(sock
= node
->outputs
.first
; sock
; sock
= sock
->next
) {
1678 sock
->stack_index
= index
++;
1680 sock
->stack_index_ext
= index_out
++;
1683 if(node
->type
==NODE_GROUP
) {
1685 node
->stack_index
= index
;
1686 index
+= ntree_begin_exec_tree((bNodeTree
*)node
->id
);
1694 /* copy socket compbufs to stack, initialize usage of curve nodes */
1695 static void composit_begin_exec(bNodeTree
*ntree
, int is_group
)
1700 for(node
= ntree
->nodes
.first
; node
; node
= node
->next
) {
1702 /* initialize needed for groups */
1706 for(sock
= node
->outputs
.first
; sock
; sock
= sock
->next
) {
1707 bNodeStack
*ns
= ntree
->stack
[0] + sock
->stack_index
;
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
);
1735 for(node
= ntree
->nodes
.first
; node
; node
= node
->next
) {
1739 for(sock
= node
->outputs
.first
; sock
; sock
= sock
->next
) {
1740 ns
= ntree
->stack
[0] + sock
->stack_index
;
1742 sock
->ns
.data
= ns
->data
;
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);
1757 /* internally, group buffers are not stored */
1758 for(ns
= ntree
->stack
[0], a
=0; a
<ntree
->stacksize
; a
++, ns
++) {
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
;
1772 stack
+= gnode
->stack_index
;
1774 for(node
= ntree
->nodes
.first
; node
; node
= node
->next
) {
1775 if(node
->typeinfo
->execfunc
) {
1778 for(sock
= node
->inputs
.first
; sock
; sock
= sock
->next
) {
1781 bNodeStack
*ns
= stack
+ sock
->link
->fromsock
->stack_index
;
1783 ns
->sockettype
= sock
->link
->fromsock
->type
;
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
)
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
) {
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
) {
1825 for(sock
= node
->inputs
.first
; sock
; sock
= sock
->next
) {
1827 ns
= ntree
->stack
[0] + sock
->link
->fromsock
->stack_index
;
1829 ns
->sockettype
= sock
->link
->fromsock
->type
;
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);
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
) {
1856 /* another callback candidate! */
1857 if(ntree
->type
==NTREE_COMPOSIT
)
1858 composit_end_exec(ntree
, 0);
1861 for(a
=0; a
<BLENDER_MAX_THREADS
; a
++)
1863 MEM_freeN(ntree
->stack
[a
]);
1865 MEM_freeN(ntree
->stack
);
1869 ntree
->init
&= ~NTREE_EXEC_INIT
;
1873 static void node_get_stack(bNode
*node
, bNodeStack
*stack
, bNodeStack
**in
, bNodeStack
**out
)
1877 /* build pointer stack */
1878 for(sock
= node
->inputs
.first
; sock
; sock
= sock
->next
) {
1880 *(in
++)= stack
+ sock
->link
->fromsock
->stack_index
;
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
)
1894 bNodeStack
*nsin
[MAX_SOCKET
]; /* arbitrary... watch this */
1895 bNodeStack
*nsout
[MAX_SOCKET
]; /* arbitrary... watch this */
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
)
1924 if(ELEM3(node
->type
, CMP_NODE_TIME
, CMP_NODE_VALUE
, CMP_NODE_RGB
))
1927 /* doing this for all node types goes wrong. memory free errors */
1928 if(node
->inputs
.first
&& node
->type
==CMP_NODE_MAP_VALUE
) {
1930 for(sock
= node
->inputs
.first
; sock
; sock
= sock
->next
) {
1932 retval
&= node_only_value(sock
->link
->fromnode
);
1940 /* not changing info, for thread callback */
1941 typedef struct 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
);
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
;
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 */
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
))
1991 for(node
= ntree
->nodes
.first
; node
; node
= node
->next
) {
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
) {
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
))
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
) {
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
;
2039 /* printf("node needs exec %s\n", node->name); */
2041 /* tag for getExecutableNode() */
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 */
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
);
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
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
)
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
;
2097 free_compbuf(ns
->data
);
2099 // printf("freed buf node %s \n", node->name);
2106 static bNode
*getExecutableNode(bNodeTree
*ntree
)
2111 for(node
= ntree
->nodes
.first
; node
; node
= node
->next
) {
2114 /* input sockets should be ready */
2115 for(sock
= node
->inputs
.first
; sock
; sock
= sock
->next
) {
2117 if((sock
->link
->fromnode
->exec
& NODE_READY
)==0)
2128 /* optimized tree execute test for compositing */
2129 void ntreeCompositExecTree(bNodeTree
*ntree
, RenderData
*rd
, int do_preview
)
2134 int totnode
, rendering
= 1;
2136 if(ntree
==NULL
) return;
2139 ntreeInitPreview(ntree
, 0, 0);
2141 ntreeBeginExecTree(ntree
);
2143 /* prevent unlucky accidents */
2145 rd
->scemode
&= ~R_COMP_CROP
;
2147 /* setup callerdata for thread callback */
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
);
2161 if(BLI_available_threads(&threads
)) {
2162 node
= getExecutableNode(ntree
);
2165 if(ntree
->timecursor
)
2166 ntree
->timecursor(totnode
);
2167 if(ntree
->stats_draw
) {
2169 sprintf(str
, "Compositing %d %s", totnode
, node
->name
);
2170 ntree
->stats_draw(str
);
2174 node
->new_node
= (bNode
*)&thdata
;
2175 node
->exec
= NODE_PROCESSING
;
2176 BLI_insert_thread(&threads
, node
);
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
);
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
)
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
)
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
);
2275 force_hidden_passes(node
, srl
->passflag
);
2277 else if( node
->type
==CMP_NODE_IMAGE
) {
2278 Image
*ima
= (Image
*)node
->id
;
2281 ImageUser
*iuser
= node
->storage
;
2282 RenderLayer
*rl
= BLI_findlink(&ima
->rr
->layers
, iuser
->layer
);
2284 force_hidden_passes(node
, rl
->passflag
);
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
);
2292 force_hidden_passes(node
, 0);
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
)
2307 for(sce
= G
.main
->scene
.first
; sce
; sce
= sce
->id
.next
) {
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
)
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
);
2335 else if(node
->type
==CMP_NODE_TIME
) {
2336 NodeTagChanged(ntree
, node
);
2339 else if(node
->type
==CMP_NODE_R_LAYERS
) {
2340 NodeTagChanged(ntree
, node
);
2343 else if(node
->type
==NODE_GROUP
) {
2344 if( ntreeCompositTagAnimated((bNodeTree
*)node
->id
) ) {
2345 NodeTagChanged(ntree
, node
);
2354 /* called from image window preview */
2355 void ntreeCompositTagGenerators(bNodeTree
*ntree
)
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
)
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
);
2386 bNodeType
*ntypen
= MEM_mallocN(sizeof(bNodeType
), "node type");
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
);