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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, 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): Bob Holcomb.
27 * ***** END GPL LICENSE BLOCK *****
30 #ifndef DISABLE_PYTHON
38 #include "DNA_anim_types.h"
40 #include "RNA_access.h"
42 #include "BKE_fcurve.h"
43 #include "BKE_animsys.h" /* BKE_free_animdata only */
48 #include "MEM_guardedalloc.h"
51 #include "intern/CMP_util.h" /* stupid include path... */
55 #include "intern/TEX_util.h"
57 #include "GPU_material.h"
59 static ListBase empty_list = {NULL, NULL};
60 ListBase node_all_composit = {NULL, NULL};
61 ListBase node_all_shaders = {NULL, NULL};
62 ListBase node_all_textures = {NULL, NULL};
64 /* ************** Type stuff ********** */
66 static bNodeType *node_get_type(bNodeTree *ntree, int type, bNodeTree *ngroup, ID *id)
68 if(type==NODE_GROUP) {
69 if(ngroup && GS(ngroup->id.name)==ID_NT) {
70 return ngroup->owntype;
75 bNodeType *ntype = ntree->alltypes.first;
76 for(; ntype; ntype= ntype->next)
77 if(ntype->type==type && id==ntype->id )
84 void ntreeInitTypes(bNodeTree *ntree)
88 if(ntree->type==NTREE_SHADER)
89 ntree->alltypes= node_all_shaders;
90 else if(ntree->type==NTREE_COMPOSIT)
91 ntree->alltypes= node_all_composit;
92 else if(ntree->type==NTREE_TEXTURE)
93 ntree->alltypes= node_all_textures;
95 ntree->alltypes= empty_list;
96 printf("Error: no type definitions for nodes\n");
99 for(node= ntree->nodes.first; node; node= next) {
101 if(node->type==NODE_DYNAMIC) {
102 bNodeType *stype= NULL;
103 if(node->id==NULL) { /* empty script node */
104 stype= node_get_type(ntree, node->type, NULL, NULL);
105 } else { /* not an empty script node */
106 stype= node_get_type(ntree, node->type, NULL, node->id);
108 stype= node_get_type(ntree, node->type, NULL, NULL);
109 /* needed info if the pynode script fails now: */
110 if (node->id) node->storage= ntree;
113 node->custom1= BSET(node->custom1,NODE_DYNAMIC_ADDEXIST);
116 node->typeinfo= stype;
117 node->typeinfo->initfunc(node);
119 node->typeinfo= node_get_type(ntree, node->type, (bNodeTree *)node->id, NULL);
122 if(node->typeinfo==NULL) {
123 printf("Error: Node type %s doesn't exist anymore, removed\n", node->name);
124 nodeFreeNode(ntree, node);
128 ntree->init |= NTREE_TYPE_INIT;
131 /* updates node with (modified) bNodeType.. this should be done for all trees */
132 void ntreeUpdateType(bNodeTree *ntree, bNodeType *ntype)
136 for(node= ntree->nodes.first; node; node= node->next) {
137 if(node->typeinfo== ntype) {
138 nodeUpdateType(ntree, node, ntype);
143 /* only used internal... we depend on type definitions! */
144 static bNodeSocket *node_add_socket_type(ListBase *lb, bNodeSocketType *stype)
146 bNodeSocket *sock= MEM_callocN(sizeof(bNodeSocket), "sock");
148 BLI_strncpy(sock->name, stype->name, NODE_MAXSTR);
149 if(stype->limit==0) sock->limit= 0xFFF;
150 else sock->limit= stype->limit;
151 sock->type= stype->type;
153 sock->to_index= stype->own_index;
154 sock->tosock= stype->internsock;
156 sock->ns.vec[0]= stype->val1;
157 sock->ns.vec[1]= stype->val2;
158 sock->ns.vec[2]= stype->val3;
159 sock->ns.vec[3]= stype->val4;
160 sock->ns.min= stype->min;
161 sock->ns.max= stype->max;
164 BLI_addtail(lb, sock);
169 static void node_rem_socket(bNodeTree *ntree, ListBase *lb, bNodeSocket *sock)
171 bNodeLink *link, *next;
173 for(link= ntree->links.first; link; link= next) {
175 if(link->fromsock==sock || link->tosock==sock) {
176 nodeRemLink(ntree, link);
180 BLI_remlink(lb, sock);
184 static bNodeSocket *verify_socket(ListBase *lb, bNodeSocketType *stype)
188 for(sock= lb->first; sock; sock= sock->next) {
189 /* both indices are zero for non-groups, otherwise it's a unique index */
190 if(sock->to_index==stype->own_index)
191 if(strncmp(sock->name, stype->name, NODE_MAXSTR)==0)
195 sock->type= stype->type; /* in future, read this from tydefs! */
196 if(stype->limit==0) sock->limit= 0xFFF;
197 else sock->limit= stype->limit;
198 sock->ns.min= stype->min;
199 sock->ns.max= stype->max;
200 sock->tosock= stype->internsock;
202 BLI_remlink(lb, sock);
207 return node_add_socket_type(NULL, stype);
211 static void verify_socket_list(bNodeTree *ntree, ListBase *lb, bNodeSocketType *stype_first)
213 bNodeSocketType *stype;
215 /* no inputs anymore? */
216 if(stype_first==NULL) {
218 node_rem_socket(ntree, lb, lb->first);
221 /* step by step compare */
223 while(stype->type != -1) {
224 stype->sock= verify_socket(lb, stype);
227 /* leftovers are removed */
229 node_rem_socket(ntree, lb, lb->first);
230 /* and we put back the verified sockets */
232 while(stype->type != -1) {
233 BLI_addtail(lb, stype->sock);
239 void nodeVerifyType(bNodeTree *ntree, bNode *node)
241 bNodeType *ntype= node->typeinfo;
244 /* might add some other verify stuff here */
246 verify_socket_list(ntree, &node->inputs, ntype->inputs);
247 verify_socket_list(ntree, &node->outputs, ntype->outputs);
251 void ntreeVerifyTypes(bNodeTree *ntree)
255 /* if((ntree->init & NTREE_TYPE_INIT)==0) */
256 ntreeInitTypes(ntree);
258 /* check inputs and outputs, and remove or insert them */
259 for(node= ntree->nodes.first; node; node= node->next)
260 nodeVerifyType(ntree, node);
264 /* ************** Group stuff ********** */
266 bNodeType node_group_typeinfo= {
267 /* next,prev */ NULL, NULL,
268 /* type code */ NODE_GROUP,
270 /* width+range */ 120, 60, 200,
271 /* class+opts */ NODE_CLASS_GROUP, NODE_OPTIONS,
272 /* input sock */ NULL,
273 /* output sock */ NULL,
278 /* freestoragefunc */ NULL,
279 /* copystoragefunc */ NULL,
283 /* tag internal sockets */
284 static void group_tag_internal_sockets(bNodeTree *ngroup)
290 /* clear intern tag, but check already for hidden sockets */
291 for(node= ngroup->nodes.first; node; node= node->next) {
292 for(sock= node->inputs.first; sock; sock= sock->next)
293 sock->intern= sock->flag & SOCK_HIDDEN;
294 for(sock= node->outputs.first; sock; sock= sock->next)
295 sock->intern= sock->flag & (SOCK_HIDDEN|SOCK_UNAVAIL);
298 for(link= ngroup->links.first; link; link= link->next) {
299 link->fromsock->intern= 1;
300 link->tosock->intern= 1;
303 /* remove link pointer to external links (only happens on create group) */
304 for(node= ngroup->nodes.first; node; node= node->next) {
305 for(sock= node->inputs.first; sock; sock= sock->next)
310 /* set all intern sockets to own_index zero, makes sure that later use won't mixup */
311 for(node= ngroup->nodes.first; node; node= node->next) {
312 for(sock= node->inputs.first; sock; sock= sock->next)
315 for(sock= node->outputs.first; sock; sock= sock->next)
321 /* after editing group, new sockets are zero */
322 /* this routine ensures unique identifiers for zero sockets that are exposed */
323 static void group_verify_own_indices(bNodeTree *ngroup)
328 for(node= ngroup->nodes.first; node; node= node->next) {
329 for(sock= node->inputs.first; sock; sock= sock->next)
330 if(sock->own_index==0 && sock->intern==0)
331 sock->own_index= ++(ngroup->cur_index);
332 for(sock= node->outputs.first; sock; sock= sock->next)
333 if(sock->own_index==0 && sock->intern==0)
334 sock->own_index= ++(ngroup->cur_index);
336 //printf("internal index %d\n", ngroup->cur_index);
340 /* nodetrees can be used as groups, so we need typeinfo structs generated */
341 void ntreeMakeOwnType(bNodeTree *ngroup)
345 int totin= 0, totout=0, a;
347 /* tags socket when internal linked */
348 group_tag_internal_sockets(ngroup);
350 /* ensure all sockets have own unique id */
351 group_verify_own_indices(ngroup);
354 for(node= ngroup->nodes.first; node; node= node->next) {
355 if(node->type==NODE_GROUP)
357 for(sock= node->inputs.first; sock; sock= sock->next)
360 for(sock= node->outputs.first; sock; sock= sock->next)
364 /* debug: nodetrees in nodetrees not handled yet */
366 printf("group in group, not supported yet\n");
370 /* free own type struct */
371 if(ngroup->owntype) {
372 if(ngroup->owntype->inputs)
373 MEM_freeN(ngroup->owntype->inputs);
374 if(ngroup->owntype->outputs)
375 MEM_freeN(ngroup->owntype->outputs);
376 MEM_freeN(ngroup->owntype);
379 /* make own type struct */
380 ngroup->owntype= MEM_callocN(sizeof(bNodeType), "group type");
381 *ngroup->owntype= node_group_typeinfo; /* copy data, for init */
383 /* input type arrays */
385 bNodeSocketType *stype;
386 bNodeSocketType *inputs= MEM_callocN(sizeof(bNodeSocketType)*(totin+1), "bNodeSocketType");
389 for(node= ngroup->nodes.first; node; node= node->next) {
390 /* nodes are presumed fully verified, stype and socket list are in sync */
391 stype= node->typeinfo->inputs;
392 for(sock= node->inputs.first; sock; sock= sock->next, stype++) {
393 if(sock->intern==0) {
394 /* debug only print */
395 if(stype==NULL || stype->type==-1) printf("group verification error %s\n", ngroup->id.name);
398 inputs[a].own_index= sock->own_index;
399 inputs[a].internsock= sock;
404 inputs[a].type= -1; /* terminator code */
405 ngroup->owntype->inputs= inputs;
408 /* output type arrays */
410 bNodeSocketType *stype;
411 bNodeSocketType *outputs= MEM_callocN(sizeof(bNodeSocketType)*(totout+1), "bNodeSocketType");
414 for(node= ngroup->nodes.first; node; node= node->next) {
415 /* nodes are presumed fully verified, stype and socket list are in sync */
416 stype= node->typeinfo->outputs;
417 for(sock= node->outputs.first; sock; sock= sock->next, stype++) {
418 if(sock->intern==0) {
419 /* debug only print */
420 if(stype==NULL || stype->type==-1) printf("group verification error %s\n", ngroup->id.name);
423 outputs[a].own_index= sock->own_index;
424 outputs[a].internsock= sock;
429 outputs[a].type= -1; /* terminator code */
430 ngroup->owntype->outputs= outputs;
433 /* voila, the nodetree has the full definition for generating group-node instances! */
437 static bNodeSocket *groupnode_find_tosock(bNode *gnode, int index)
441 for(sock= gnode->inputs.first; sock; sock= sock->next)
442 if(sock->to_index==index)
447 static bNodeSocket *groupnode_find_fromsock(bNode *gnode, int index)
451 for(sock= gnode->outputs.first; sock; sock= sock->next)
452 if(sock->to_index==index)
457 bNode *nodeMakeGroupFromSelected(bNodeTree *ntree)
459 bNodeLink *link, *linkn;
460 bNode *node, *gnode, *nextn;
463 float min[2], max[2];
466 INIT_MINMAX2(min, max);
468 /* is there something to group? also do some clearing */
469 for(node= ntree->nodes.first; node; node= node->next) {
470 if(node->flag & NODE_SELECT) {
471 /* no groups in groups */
472 if(node->type==NODE_GROUP)
474 DO_MINMAX2( (&node->locx), min, max);
479 if(totnode==0) return NULL;
481 /* check if all connections are OK, no unselected node has both
482 inputs and outputs to a selection */
483 for(link= ntree->links.first; link; link= link->next) {
484 if(link->fromnode->flag & NODE_SELECT)
485 link->tonode->done |= 1;
486 if(link->tonode->flag & NODE_SELECT)
487 link->fromnode->done |= 2;
490 for(node= ntree->nodes.first; node; node= node->next) {
491 if((node->flag & NODE_SELECT)==0)
498 /* OK! new nodetree */
499 ngroup= alloc_libblock(&G.main->nodetree, ID_NT, "NodeGroup");
500 ngroup->type= ntree->type;
501 ngroup->alltypes= ntree->alltypes;
503 /* move nodes over */
504 for(node= ntree->nodes.first; node; node= nextn) {
506 if(node->flag & NODE_SELECT) {
507 BLI_remlink(&ntree->nodes, node);
508 BLI_addtail(&ngroup->nodes, node);
509 node->locx-= 0.5f*(min[0]+max[0]);
510 node->locy-= 0.5f*(min[1]+max[1]);
512 /* set socket own_index to zero since it can still have a value
513 * from being in a group before, otherwise it doesn't get a unique
514 * index in group_verify_own_indices */
515 for(sock= node->inputs.first; sock; sock= sock->next)
517 for(sock= node->outputs.first; sock; sock= sock->next)
522 /* move links over */
523 for(link= ntree->links.first; link; link= linkn) {
525 if(link->fromnode->flag & link->tonode->flag & NODE_SELECT) {
526 BLI_remlink(&ntree->links, link);
527 BLI_addtail(&ngroup->links, link);
531 /* now we can make own group typeinfo */
532 ntreeMakeOwnType(ngroup);
534 /* make group node */
535 gnode= nodeAddNodeType(ntree, NODE_GROUP, ngroup, NULL);
536 gnode->locx= 0.5f*(min[0]+max[0]);
537 gnode->locy= 0.5f*(min[1]+max[1]);
539 /* relink external sockets */
540 for(link= ntree->links.first; link; link= linkn) {
543 if(link->tonode->flag & NODE_SELECT) {
545 sock= groupnode_find_tosock(gnode, link->tosock->own_index);
547 nodeRemLink(ntree, link);
548 printf("Removed link, cannot mix internal and external sockets in group\n");
550 else link->tosock= sock;
552 else if(link->fromnode->flag & NODE_SELECT) {
553 link->fromnode= gnode;
554 sock= groupnode_find_fromsock(gnode, link->fromsock->own_index);
556 nodeRemLink(ntree, link);
557 printf("Removed link, cannot mix internal and external sockets in group\n");
559 else link->fromsock= sock;
563 /* initialize variables of unused input sockets */
564 for(node= ngroup->nodes.first; node; node= node->next) {
565 for(sock= node->inputs.first; sock; sock= sock->next) {
566 if(sock->intern==0) {
567 bNodeSocket *nsock= groupnode_find_tosock(gnode, sock->own_index);
569 QUATCOPY(nsock->ns.vec, sock->ns.vec);
575 /* update node levels */
576 ntreeSolveOrder(ntree);
581 /* note: ungroup: group_indices zero! */
583 /* here's a nasty little one, need to check users... */
584 /* should become callbackable... */
585 void nodeVerifyGroup(bNodeTree *ngroup)
588 /* group changed, so we rebuild the type definition */
589 ntreeMakeOwnType(ngroup);
591 if(ngroup->type==NTREE_SHADER) {
593 for(ma= G.main->mat.first; ma; ma= ma->id.next) {
597 /* find if group is in tree */
598 for(node= ma->nodetree->nodes.first; node; node= node->next)
599 if(node->id == (ID *)ngroup)
603 /* set all type pointers OK */
604 ntreeInitTypes(ma->nodetree);
606 for(node= ma->nodetree->nodes.first; node; node= node->next)
607 if(node->id == (ID *)ngroup)
608 nodeVerifyType(ma->nodetree, node);
613 else if(ngroup->type==NTREE_COMPOSIT) {
615 for(sce= G.main->scene.first; sce; sce= sce->id.next) {
619 /* find if group is in tree */
620 for(node= sce->nodetree->nodes.first; node; node= node->next)
621 if(node->id == (ID *)ngroup)
625 /* set all type pointers OK */
626 ntreeInitTypes(sce->nodetree);
628 for(node= sce->nodetree->nodes.first; node; node= node->next)
629 if(node->id == (ID *)ngroup)
630 nodeVerifyType(sce->nodetree, node);
635 else if(ngroup->type==NTREE_TEXTURE) {
637 for(tx= G.main->tex.first; tx; tx= tx->id.next) {
641 /* find if group is in tree */
642 for(node= tx->nodetree->nodes.first; node; node= node->next)
643 if(node->id == (ID *)ngroup)
647 /* set all type pointers OK */
648 ntreeInitTypes(tx->nodetree);
650 for(node= tx->nodetree->nodes.first; node; node= node->next)
651 if(node->id == (ID *)ngroup)
652 nodeVerifyType(tx->nodetree, node);
659 /* also to check all users of groups. Now only used in editor for hide/unhide */
660 /* should become callbackable? */
661 void nodeGroupSocketUseFlags(bNodeTree *ngroup)
667 for(node= ngroup->nodes.first; node; node= node->next) {
668 for(sock= node->inputs.first; sock; sock= sock->next)
669 sock->flag &= ~SOCK_IN_USE;
670 for(sock= node->outputs.first; sock; sock= sock->next)
671 sock->flag &= ~SOCK_IN_USE;
674 /* tag all thats in use */
675 if(ngroup->type==NTREE_SHADER) {
677 for(ma= G.main->mat.first; ma; ma= ma->id.next) {
679 for(node= ma->nodetree->nodes.first; node; node= node->next) {
680 if(node->id==(ID *)ngroup) {
681 for(sock= node->inputs.first; sock; sock= sock->next)
684 sock->tosock->flag |= SOCK_IN_USE;
685 for(sock= node->outputs.first; sock; sock= sock->next)
686 if(nodeCountSocketLinks(ma->nodetree, sock))
688 sock->tosock->flag |= SOCK_IN_USE;
694 else if(ngroup->type==NTREE_COMPOSIT) {
696 for(sce= G.main->scene.first; sce; sce= sce->id.next) {
698 for(node= sce->nodetree->nodes.first; node; node= node->next) {
699 if(node->id==(ID *)ngroup) {
700 for(sock= node->inputs.first; sock; sock= sock->next)
703 sock->tosock->flag |= SOCK_IN_USE;
704 for(sock= node->outputs.first; sock; sock= sock->next)
705 if(nodeCountSocketLinks(sce->nodetree, sock))
707 sock->tosock->flag |= SOCK_IN_USE;
713 else if(ngroup->type==NTREE_TEXTURE) {
715 for(tx= G.main->tex.first; tx; tx= tx->id.next) {
717 for(node= tx->nodetree->nodes.first; node; node= node->next) {
718 if(node->id==(ID *)ngroup) {
719 for(sock= node->inputs.first; sock; sock= sock->next)
722 sock->tosock->flag |= SOCK_IN_USE;
723 for(sock= node->outputs.first; sock; sock= sock->next)
724 if(nodeCountSocketLinks(tx->nodetree, sock))
726 sock->tosock->flag |= SOCK_IN_USE;
734 /* finds a node based on its name */
735 bNode *nodeFindNodebyName(bNodeTree *ntree, const char *name)
739 for(node= ntree->nodes.first; node; node= node->next) {
740 if (strcmp(name, node->name) == 0)
746 /* finds a node based on given socket */
747 int nodeFindNode(bNodeTree *ntree, bNodeSocket *sock, bNode **nodep, int *sockindex)
753 for(node= ntree->nodes.first; node; node= node->next) {
754 for(index=0, tsock= node->inputs.first; tsock; tsock= tsock->next, index++)
759 for(index=0, tsock= node->outputs.first; tsock; tsock= tsock->next, index++)
768 if(sockindex) *sockindex= index;
776 /* returns 1 if its OK */
777 int nodeGroupUnGroup(bNodeTree *ntree, bNode *gnode)
779 bNodeLink *link, *linkn;
781 bNodeTree *ngroup, *wgroup;
784 ngroup= (bNodeTree *)gnode->id;
785 if(ngroup==NULL) return 0;
787 /* clear new pointers, set in copytree */
788 for(node= ntree->nodes.first; node; node= node->next)
789 node->new_node= NULL;
791 wgroup= ntreeCopyTree(ngroup, 0);
793 /* add the nodes into the ntree */
794 for(node= wgroup->nodes.first; node; node= nextn) {
796 BLI_remlink(&wgroup->nodes, node);
797 BLI_addtail(&ntree->nodes, node);
798 node->locx+= gnode->locx;
799 node->locy+= gnode->locy;
800 node->flag |= NODE_SELECT;
802 /* and the internal links */
803 for(link= wgroup->links.first; link; link= linkn) {
805 BLI_remlink(&wgroup->links, link);
806 BLI_addtail(&ntree->links, link);
809 /* restore links to and from the gnode */
810 for(link= ntree->links.first; link; link= link->next) {
811 if(link->tonode==gnode) {
812 /* link->tosock->tosock is on the node we look for */
813 nodeFindNode(ngroup, link->tosock->tosock, &nextn, &index);
814 if(nextn==NULL) printf("wrong stuff!\n");
815 else if(nextn->new_node==NULL) printf("wrong stuff too!\n");
817 link->tonode= nextn->new_node;
818 link->tosock= BLI_findlink(&link->tonode->inputs, index);
821 else if(link->fromnode==gnode) {
822 /* link->fromsock->tosock is on the node we look for */
823 nodeFindNode(ngroup, link->fromsock->tosock, &nextn, &index);
824 if(nextn==NULL) printf("1 wrong stuff!\n");
825 else if(nextn->new_node==NULL) printf("1 wrong stuff too!\n");
827 link->fromnode= nextn->new_node;
828 link->fromsock= BLI_findlink(&link->fromnode->outputs, index);
833 /* remove the gnode & work tree */
834 free_libblock(&G.main->nodetree, wgroup);
836 nodeFreeNode(ntree, gnode);
838 /* solve order goes fine, but the level tags not... doing it twice works for now. solve this once */
839 ntreeSolveOrder(ntree);
840 ntreeSolveOrder(ntree);
845 void nodeCopyGroup(bNode *gnode)
850 gnode->id= (ID *)ntreeCopyTree((bNodeTree *)gnode->id, 0);
852 /* new_sock was set in nodeCopyNode */
853 for(sock=gnode->inputs.first; sock; sock=sock->next)
855 sock->tosock= sock->tosock->new_sock;
857 for(sock=gnode->outputs.first; sock; sock=sock->next)
859 sock->tosock= sock->tosock->new_sock;
862 /* ************** Add stuff ********** */
863 void nodeAddSockets(bNode *node, bNodeType *ntype)
865 bNodeSocketType *stype;
868 stype= ntype->inputs;
869 while(stype->type != -1) {
870 node_add_socket_type(&node->inputs, stype);
875 stype= ntype->outputs;
876 while(stype->type != -1) {
877 node_add_socket_type(&node->outputs, stype);
882 /* Find the first available, non-duplicate name for a given node */
883 void nodeUniqueName(bNodeTree *ntree, bNode *node)
885 BLI_uniquename(&ntree->nodes, node, "Node", '.', offsetof(bNode, name), sizeof(node->name));
888 bNode *nodeAddNodeType(bNodeTree *ntree, int type, bNodeTree *ngroup, ID *id)
891 bNodeType *ntype= NULL;
893 if(type>=NODE_DYNAMIC_MENU) {
894 int a=0, idx= type-NODE_DYNAMIC_MENU;
895 ntype= ntree->alltypes.first;
897 if(ntype->type==NODE_DYNAMIC) {
905 ntype= node_get_type(ntree, type, ngroup, id);
907 node= MEM_callocN(sizeof(bNode), "new node");
908 BLI_addtail(&ntree->nodes, node);
909 node->typeinfo= ntype;
910 if(type>=NODE_DYNAMIC_MENU)
911 node->custom2= type; /* for node_dynamic_init */
914 BLI_strncpy(node->name, ngroup->id.name+2, NODE_MAXSTR);
915 else if(type>NODE_DYNAMIC_MENU) {
916 BLI_strncpy(node->name, ntype->id->name+2, NODE_MAXSTR);
919 BLI_strncpy(node->name, ntype->name, NODE_MAXSTR);
921 nodeUniqueName(ntree, node);
923 node->type= ntype->type;
924 node->flag= NODE_SELECT|ntype->flag;
925 node->width= ntype->width;
926 node->miniwidth= 42.0f; /* small value only, allows print of first chars */
929 node->id= (ID *)ngroup;
931 /* need init handler later? */
933 if(ntype->initfunc!=NULL)
934 ntype->initfunc(node);
936 nodeAddSockets(node, ntype);
941 void nodeMakeDynamicType(bNode *node)
943 /* find SH_DYNAMIC_NODE ntype */
944 bNodeType *ntype= node_all_shaders.first;
946 if(ntype->type==NODE_DYNAMIC && ntype->id==NULL)
951 /* make own type struct to fill */
953 /*node->typeinfo= MEM_dupallocN(ntype);*/
954 bNodeType *newtype= MEM_callocN(sizeof(bNodeType), "dynamic bNodeType");
956 newtype->name= BLI_strdup(ntype->name);
957 node->typeinfo= newtype;
961 void nodeUpdateType(bNodeTree *ntree, bNode* node, bNodeType *ntype)
963 verify_socket_list(ntree, &node->inputs, ntype->inputs);
964 verify_socket_list(ntree, &node->outputs, ntype->outputs);
967 /* keep socket listorder identical, for copying links */
968 /* ntree is the target tree */
969 bNode *nodeCopyNode(struct bNodeTree *ntree, struct bNode *node, int internal)
971 bNode *nnode= MEM_callocN(sizeof(bNode), "dupli node");
972 bNodeSocket *sock, *oldsock;
975 nodeUniqueName(ntree, nnode);
977 BLI_addtail(&ntree->nodes, nnode);
979 BLI_duplicatelist(&nnode->inputs, &node->inputs);
980 oldsock= node->inputs.first;
981 for(sock= nnode->inputs.first; sock; sock= sock->next, oldsock= oldsock->next) {
982 oldsock->new_sock= sock;
987 BLI_duplicatelist(&nnode->outputs, &node->outputs);
988 oldsock= node->outputs.first;
989 for(sock= nnode->outputs.first; sock; sock= sock->next, oldsock= oldsock->next) {
992 sock->stack_index= 0;
994 oldsock->new_sock= sock;
997 /* don't increase node->id users, freenode doesn't decrement either */
999 if(node->typeinfo->copystoragefunc)
1000 node->typeinfo->copystoragefunc(node, nnode);
1002 node->new_node= nnode;
1003 nnode->new_node= NULL;
1004 nnode->preview= NULL;
1009 bNodeLink *nodeAddLink(bNodeTree *ntree, bNode *fromnode, bNodeSocket *fromsock, bNode *tonode, bNodeSocket *tosock)
1011 bNodeLink *link= MEM_callocN(sizeof(bNodeLink), "link");
1013 BLI_addtail(&ntree->links, link);
1014 link->fromnode= fromnode;
1015 link->fromsock= fromsock;
1016 link->tonode= tonode;
1017 link->tosock= tosock;
1022 void nodeRemLink(bNodeTree *ntree, bNodeLink *link)
1024 BLI_remlink(&ntree->links, link);
1026 link->tosock->link= NULL;
1030 void nodeRemSocketLinks(bNodeTree *ntree, bNodeSocket *sock)
1032 bNodeLink *link, *next;
1034 for(link= ntree->links.first; link; link= next) {
1036 if(link->fromsock==sock || link->tosock==sock) {
1037 nodeRemLink(ntree, link);
1043 bNodeTree *ntreeAddTree(int type)
1045 bNodeTree *ntree= MEM_callocN(sizeof(bNodeTree), "new node tree");
1047 ntree->alltypes.first = NULL;
1048 ntree->alltypes.last = NULL;
1050 /* this helps RNA identify ID pointers as nodetree */
1051 if(ntree->type==NTREE_SHADER)
1052 BLI_strncpy(ntree->id.name, "NTShader Nodetree", sizeof(ntree->id.name));
1053 else if(ntree->type==NTREE_COMPOSIT)
1054 BLI_strncpy(ntree->id.name, "NTCompositing Nodetree", sizeof(ntree->id.name));
1055 else if(ntree->type==NTREE_TEXTURE)
1056 BLI_strncpy(ntree->id.name, "NTTexture Nodetree", sizeof(ntree->id.name));
1058 ntreeInitTypes(ntree);
1062 /* Warning: this function gets called during some rather unexpected times
1063 * - internal_select is only 1 when used for duplicating selected nodes (i.e. Shift-D duplicate operator)
1064 * - this gets called when executing compositing updates (for threaded previews)
1065 * - when the nodetree datablock needs to be copied (i.e. when users get copied)
1067 bNodeTree *ntreeCopyTree(bNodeTree *ntree, int internal_select)
1070 bNode *node, *nnode, *last;
1071 bNodeLink *link, *nlink;
1075 if(ntree==NULL) return NULL;
1077 if(internal_select==0) {
1078 /* is ntree part of library? */
1079 for(newtree=G.main->nodetree.first; newtree; newtree= newtree->id.next)
1080 if(newtree==ntree) break;
1082 newtree= copy_libblock(ntree);
1084 newtree= MEM_dupallocN(ntree);
1085 copy_libblock_data(&newtree->id, &ntree->id); /* copy animdata and ID props */
1087 newtree->nodes.first= newtree->nodes.last= NULL;
1088 newtree->links.first= newtree->links.last= NULL;
1093 last= ntree->nodes.last;
1094 for(node= ntree->nodes.first; node; node= node->next) {
1096 node->new_node= NULL;
1097 if(internal_select==0 || (node->flag & NODE_SELECT)) {
1098 nnode= nodeCopyNode(newtree, node, internal_select); /* sets node->new */
1099 if(internal_select) {
1100 node->flag &= ~(NODE_SELECT|NODE_ACTIVE);
1101 nnode->flag |= NODE_SELECT;
1104 if(node==last) break;
1107 /* check for copying links */
1108 for(link= ntree->links.first; link; link= link->next) {
1109 if(link->fromnode==NULL || link->tonode==NULL);
1110 else if(link->fromnode->new_node && link->tonode->new_node) {
1111 nlink= nodeAddLink(newtree, link->fromnode->new_node, NULL, link->tonode->new_node, NULL);
1112 /* sockets were copied in order */
1113 for(a=0, sock= link->fromnode->outputs.first; sock; sock= sock->next, a++) {
1114 if(sock==link->fromsock)
1117 nlink->fromsock= BLI_findlink(&link->fromnode->new_node->outputs, a);
1119 for(a=0, sock= link->tonode->inputs.first; sock; sock= sock->next, a++) {
1120 if(sock==link->tosock)
1123 nlink->tosock= BLI_findlink(&link->tonode->new_node->inputs, a);
1127 /* own type definition for group usage */
1128 if(internal_select==0) {
1129 if(ntree->owntype) {
1130 newtree->owntype= MEM_dupallocN(ntree->owntype);
1131 if(ntree->owntype->inputs)
1132 newtree->owntype->inputs= MEM_dupallocN(ntree->owntype->inputs);
1133 if(ntree->owntype->outputs)
1134 newtree->owntype->outputs= MEM_dupallocN(ntree->owntype->outputs);
1137 /* weird this is required... there seem to be link pointers wrong still? */
1138 /* anyhoo, doing this solves crashes on copying entire tree (copy scene) and delete nodes */
1139 ntreeSolveOrder(newtree);
1144 /* *************** preview *********** */
1145 /* if node->preview, then we assume the rect to exist */
1147 static void node_free_preview(bNode *node)
1150 if(node->preview->rect)
1151 MEM_freeN(node->preview->rect);
1152 MEM_freeN(node->preview);
1153 node->preview= NULL;
1157 static void node_init_preview(bNode *node, int xsize, int ysize)
1160 if(node->preview==NULL) {
1161 node->preview= MEM_callocN(sizeof(bNodePreview), "node preview");
1162 // printf("added preview %s\n", node->name);
1165 /* node previews can get added with variable size this way */
1166 if(xsize==0 || ysize==0)
1169 /* sanity checks & initialize */
1170 if(node->preview->rect) {
1171 if(node->preview->xsize!=xsize && node->preview->ysize!=ysize) {
1172 MEM_freeN(node->preview->rect);
1173 node->preview->rect= NULL;
1177 if(node->preview->rect==NULL) {
1178 node->preview->rect= MEM_callocN(4*xsize + xsize*ysize*sizeof(float)*4, "node preview rect");
1179 node->preview->xsize= xsize;
1180 node->preview->ysize= ysize;
1183 memset(node->preview->rect, 0, 4*xsize + xsize*ysize*sizeof(float)*4);
1186 void ntreeInitPreview(bNodeTree *ntree, int xsize, int ysize)
1193 for(node= ntree->nodes.first; node; node= node->next) {
1194 if(node->typeinfo->flag & NODE_PREVIEW) /* hrms, check for closed nodes? */
1195 node_init_preview(node, xsize, ysize);
1196 if(node->type==NODE_GROUP && (node->flag & NODE_GROUP_EDIT))
1197 ntreeInitPreview((bNodeTree *)node->id, xsize, ysize);
1201 static void nodeClearPreview(bNode *node)
1203 if(node->preview && node->preview->rect)
1204 memset(node->preview->rect, 0, MEM_allocN_len(node->preview->rect));
1207 /* use it to enforce clear */
1208 void ntreeClearPreview(bNodeTree *ntree)
1215 for(node= ntree->nodes.first; node; node= node->next) {
1216 if(node->typeinfo->flag & NODE_PREVIEW)
1217 nodeClearPreview(node);
1218 if(node->type==NODE_GROUP && (node->flag & NODE_GROUP_EDIT))
1219 ntreeClearPreview((bNodeTree *)node->id);
1223 /* hack warning! this function is only used for shader previews, and
1224 since it gets called multiple times per pixel for Ztransp we only
1225 add the color once. Preview gets cleared before it starts render though */
1226 void nodeAddToPreview(bNode *node, float *col, int x, int y)
1228 bNodePreview *preview= node->preview;
1231 if(x<preview->xsize && y<preview->ysize) {
1232 unsigned char *tar= preview->rect+ 4*((preview->xsize*y) + x);
1233 //if(tar[0]==0.0f) {
1234 tar[0]= FTOCHAR(col[0]);
1235 tar[1]= FTOCHAR(col[1]);
1236 tar[2]= FTOCHAR(col[2]);
1237 tar[3]= FTOCHAR(col[3]);
1240 //else printf("prv out bound x y %d %d\n", x, y);
1242 //else printf("prv out bound x y %d %d\n", x, y);
1247 /* ************** Free stuff ********** */
1249 /* goes over entire tree */
1250 void nodeUnlinkNode(bNodeTree *ntree, bNode *node)
1252 bNodeLink *link, *next;
1256 for(link= ntree->links.first; link; link= next) {
1259 if(link->fromnode==node) {
1261 NodeTagChanged(ntree, link->tonode);
1263 else if(link->tonode==node)
1269 for(sock= lb->first; sock; sock= sock->next) {
1270 if(link->fromsock==sock || link->tosock==sock)
1274 nodeRemLink(ntree, link);
1280 static void composit_free_node_cache(bNode *node)
1284 for(sock= node->outputs.first; sock; sock= sock->next) {
1286 free_compbuf(sock->ns.data);
1287 sock->ns.data= NULL;
1292 void nodeFreeNode(bNodeTree *ntree, bNode *node)
1294 nodeUnlinkNode(ntree, node);
1295 BLI_remlink(&ntree->nodes, node);
1297 /* since it is called while free database, node->id is undefined */
1299 if(ntree->type==NTREE_COMPOSIT)
1300 composit_free_node_cache(node);
1301 BLI_freelistN(&node->inputs);
1302 BLI_freelistN(&node->outputs);
1304 node_free_preview(node);
1306 if(node->typeinfo && node->typeinfo->freestoragefunc) {
1307 node->typeinfo->freestoragefunc(node);
1313 /* do not free ntree itself here, free_libblock calls this function too */
1314 void ntreeFreeTree(bNodeTree *ntree)
1318 if(ntree==NULL) return;
1320 ntreeEndExecTree(ntree); /* checks for if it is still initialized */
1322 BKE_free_animdata((ID *)ntree);
1324 BLI_freelistN(&ntree->links); /* do first, then unlink_node goes fast */
1326 for(node= ntree->nodes.first; node; node= next) {
1328 nodeFreeNode(ntree, node);
1331 if(ntree->owntype) {
1332 if(ntree->owntype->inputs)
1333 MEM_freeN(ntree->owntype->inputs);
1334 if(ntree->owntype->outputs)
1335 MEM_freeN(ntree->owntype->outputs);
1336 MEM_freeN(ntree->owntype);
1340 void ntreeFreeCache(bNodeTree *ntree)
1344 if(ntree==NULL) return;
1346 if(ntree->type==NTREE_COMPOSIT)
1347 for(node= ntree->nodes.first; node; node= node->next)
1348 composit_free_node_cache(node);
1352 void ntreeMakeLocal(bNodeTree *ntree)
1356 /* - only lib users: do nothing
1357 * - only local users: set flag
1358 * - mixed: make copy
1361 if(ntree->id.lib==NULL) return;
1362 if(ntree->id.us==1) {
1364 ntree->id.flag= LIB_LOCAL;
1365 new_id(0, (ID *)ntree, 0);
1369 /* now check users of groups... again typedepending, callback... */
1370 if(ntree->type==NTREE_SHADER) {
1372 for(ma= G.main->mat.first; ma; ma= ma->id.next) {
1376 /* find if group is in tree */
1377 for(node= ma->nodetree->nodes.first; node; node= node->next) {
1378 if(node->id == (ID *)ntree) {
1379 if(ma->id.lib) lib= 1;
1386 else if(ntree->type==NTREE_COMPOSIT) {
1388 for(sce= G.main->scene.first; sce; sce= sce->id.next) {
1392 /* find if group is in tree */
1393 for(node= sce->nodetree->nodes.first; node; node= node->next) {
1394 if(node->id == (ID *)ntree) {
1395 if(sce->id.lib) lib= 1;
1402 else if(ntree->type==NTREE_TEXTURE) {
1404 for(tx= G.main->tex.first; tx; tx= tx->id.next) {
1408 /* find if group is in tree */
1409 for(node= tx->nodetree->nodes.first; node; node= node->next) {
1410 if(node->id == (ID *)ntree) {
1411 if(tx->id.lib) lib= 1;
1419 /* if all users are local, we simply make tree local */
1420 if(local && lib==0) {
1421 ntree->id.lib= NULL;
1422 ntree->id.flag= LIB_LOCAL;
1423 new_id(0, (ID *)ntree, 0);
1425 else if(local && lib) {
1426 /* this is the mixed case, we copy the tree and assign it to local users */
1427 bNodeTree *newtree= ntreeCopyTree(ntree, 0);
1431 if(ntree->type==NTREE_SHADER) {
1433 for(ma= G.main->mat.first; ma; ma= ma->id.next) {
1437 /* find if group is in tree */
1438 for(node= ma->nodetree->nodes.first; node; node= node->next) {
1439 if(node->id == (ID *)ntree) {
1440 if(ma->id.lib==NULL) {
1441 node->id= &newtree->id;
1450 else if(ntree->type==NTREE_COMPOSIT) {
1452 for(sce= G.main->scene.first; sce; sce= sce->id.next) {
1456 /* find if group is in tree */
1457 for(node= sce->nodetree->nodes.first; node; node= node->next) {
1458 if(node->id == (ID *)ntree) {
1459 if(sce->id.lib==NULL) {
1460 node->id= &newtree->id;
1469 else if(ntree->type==NTREE_TEXTURE) {
1471 for(tx= G.main->tex.first; tx; tx= tx->id.next) {
1475 /* find if group is in tree */
1476 for(node= tx->nodetree->nodes.first; node; node= node->next) {
1477 if(node->id == (ID *)ntree) {
1478 if(tx->id.lib==NULL) {
1479 node->id= &newtree->id;
1492 /* ************ find stuff *************** */
1494 static int ntreeHasType(bNodeTree *ntree, int type)
1499 for(node= ntree->nodes.first; node; node= node->next)
1500 if(node->type == type)
1505 bNodeLink *nodeFindLink(bNodeTree *ntree, bNodeSocket *from, bNodeSocket *to)
1509 for(link= ntree->links.first; link; link= link->next) {
1510 if(link->fromsock==from && link->tosock==to)
1512 if(link->fromsock==to && link->tosock==from) /* hrms? */
1518 int nodeCountSocketLinks(bNodeTree *ntree, bNodeSocket *sock)
1523 for(link= ntree->links.first; link; link= link->next) {
1524 if(link->fromsock==sock || link->tosock==sock)
1530 bNode *nodeGetActive(bNodeTree *ntree)
1534 if(ntree==NULL) return NULL;
1536 for(node= ntree->nodes.first; node; node= node->next)
1537 if(node->flag & NODE_ACTIVE)
1542 /* two active flags, ID nodes have special flag for buttons display */
1543 bNode *nodeGetActiveID(bNodeTree *ntree, short idtype)
1547 if(ntree==NULL) return NULL;
1549 /* check for group edit */
1550 for(node= ntree->nodes.first; node; node= node->next)
1551 if(node->flag & NODE_GROUP_EDIT)
1555 ntree= (bNodeTree*)node->id;
1557 /* now find active node with this id */
1558 for(node= ntree->nodes.first; node; node= node->next)
1559 if(node->id && GS(node->id->name)==idtype)
1560 if(node->flag & NODE_ACTIVE_ID)
1566 int nodeSetActiveID(bNodeTree *ntree, short idtype, ID *id)
1571 if(ntree==NULL) return ok;
1573 /* check for group edit */
1574 for(node= ntree->nodes.first; node; node= node->next)
1575 if(node->flag & NODE_GROUP_EDIT)
1579 ntree= (bNodeTree*)node->id;
1581 /* now find active node with this id */
1582 for(node= ntree->nodes.first; node; node= node->next) {
1583 if(node->id && GS(node->id->name)==idtype) {
1584 if(id && ok==FALSE && node->id==id) {
1585 node->flag |= NODE_ACTIVE_ID;
1588 node->flag &= ~NODE_ACTIVE_ID;
1597 /* two active flags, ID nodes have special flag for buttons display */
1598 void nodeClearActiveID(bNodeTree *ntree, short idtype)
1602 if(ntree==NULL) return;
1604 for(node= ntree->nodes.first; node; node= node->next)
1605 if(node->id && GS(node->id->name)==idtype)
1606 node->flag &= ~NODE_ACTIVE_ID;
1609 /* two active flags, ID nodes have special flag for buttons display */
1610 void nodeSetActive(bNodeTree *ntree, bNode *node)
1614 /* make sure only one node is active, and only one per ID type */
1615 for(tnode= ntree->nodes.first; tnode; tnode= tnode->next) {
1616 tnode->flag &= ~NODE_ACTIVE;
1618 if(node->id && tnode->id) {
1619 if(GS(node->id->name) == GS(tnode->id->name))
1620 tnode->flag &= ~NODE_ACTIVE_ID;
1624 node->flag |= NODE_ACTIVE;
1626 node->flag |= NODE_ACTIVE_ID;
1629 /* use flags are not persistant yet, groups might need different tagging, so we do it each time
1630 when we need to get this info */
1631 void ntreeSocketUseFlags(bNodeTree *ntree)
1638 for(node= ntree->nodes.first; node; node= node->next) {
1639 for(sock= node->inputs.first; sock; sock= sock->next)
1640 sock->flag &= ~SOCK_IN_USE;
1641 for(sock= node->outputs.first; sock; sock= sock->next)
1642 sock->flag &= ~SOCK_IN_USE;
1645 /* tag all thats in use */
1646 for(link= ntree->links.first; link; link= link->next) {
1648 if(link->fromsock) // FIXME, see below
1649 link->fromsock->flag |= SOCK_IN_USE;
1650 if(link->tosock) // FIXME This can be NULL, when dragging a new link in the UI, should probably copy the node tree for preview render - campbell
1651 link->tosock->flag |= SOCK_IN_USE;
1655 /* ************** dependency stuff *********** */
1657 /* node is guaranteed to be not checked before */
1658 static int node_recurs_check(bNode *node, bNode ***nsort, int level)
1662 int has_inputlinks= 0;
1667 for(sock= node->inputs.first; sock; sock= sock->next) {
1670 fromnode= sock->link->fromnode;
1671 if(fromnode->done==0) {
1672 fromnode->level= node_recurs_check(fromnode, nsort, level);
1676 // printf("node sort %s level %d\n", node->name, level);
1686 void ntreeSolveOrder(bNodeTree *ntree)
1688 bNode *node, **nodesort, **nsort;
1693 /* the solve-order is called on each tree change, so we should be sure no exec can be running */
1694 ntreeEndExecTree(ntree);
1696 /* set links pointers the input sockets, to find dependencies */
1697 /* first clear data */
1698 for(node= ntree->nodes.first; node; node= node->next) {
1701 for(sock= node->inputs.first; sock; sock= sock->next)
1707 for(link= ntree->links.first; link; link= link->next) {
1708 link->tosock->link= link;
1711 nsort= nodesort= MEM_callocN(totnode*sizeof(void *), "sorted node array");
1713 /* recursive check */
1714 for(node= ntree->nodes.first; node; node= node->next) {
1716 node->level= node_recurs_check(node, &nsort, 0);
1720 /* re-insert nodes in order, first a paranoia check */
1721 for(a=0; a<totnode; a++) {
1722 if(nodesort[a]==NULL)
1726 printf("sort error in node tree");
1728 ntree->nodes.first= ntree->nodes.last= NULL;
1729 for(a=0; a<totnode; a++)
1730 BLI_addtail(&ntree->nodes, nodesort[a]);
1733 MEM_freeN(nodesort);
1735 /* find the active outputs, might become tree type dependant handler */
1736 for(node= ntree->nodes.first; node; node= node->next) {
1737 if(node->typeinfo->nclass==NODE_CLASS_OUTPUT) {
1741 /* we need a check for which output node should be tagged like this, below an exception */
1742 if(node->type==CMP_NODE_OUTPUT_FILE)
1745 /* there is more types having output class, each one is checked */
1746 for(tnode= ntree->nodes.first; tnode; tnode= tnode->next) {
1747 if(tnode->typeinfo->nclass==NODE_CLASS_OUTPUT) {
1748 if(tnode->type==node->type) {
1749 if(tnode->flag & NODE_DO_OUTPUT) {
1752 tnode->flag &= ~NODE_DO_OUTPUT;
1758 node->flag |= NODE_DO_OUTPUT;
1762 /* here we could recursively set which nodes have to be done,
1763 might be different for editor or for "real" use... */
1766 /* Should be callback! */
1767 /* Do not call execs here */
1768 void NodeTagChanged(bNodeTree *ntree, bNode *node)
1770 if(ntree->type==NTREE_COMPOSIT) {
1773 for(sock= node->outputs.first; sock; sock= sock->next) {
1775 //free_compbuf(sock->ns.data);
1776 //sock->ns.data= NULL;
1783 void NodeTagIDChanged(bNodeTree *ntree, ID *id)
1788 if(ntree->type==NTREE_COMPOSIT) {
1791 for(node= ntree->nodes.first; node; node= node->next)
1793 NodeTagChanged(ntree, node);
1799 /* ******************* executing ************* */
1801 /* see notes at ntreeBeginExecTree */
1802 static void group_node_get_stack(bNode *node, bNodeStack *stack, bNodeStack **in, bNodeStack **out, bNodeStack **gin, bNodeStack **gout)
1806 /* build pointer stack */
1807 for(sock= node->inputs.first; sock; sock= sock->next) {
1809 /* yep, intern can have link or is hidden socket */
1811 *(in++)= stack + sock->link->fromsock->stack_index;
1816 *(in++)= gin[sock->stack_index_ext];
1819 for(sock= node->outputs.first; sock; sock= sock->next) {
1821 *(out++)= stack + sock->stack_index;
1823 *(out++)= gout[sock->stack_index_ext];
1827 static void node_group_execute(bNodeStack *stack, void *data, bNode *gnode, bNodeStack **in, bNodeStack **out)
1830 bNodeTree *ntree= (bNodeTree *)gnode->id;
1831 bNodeStack *nsin[MAX_SOCKET]; /* arbitrary... watch this */
1832 bNodeStack *nsout[MAX_SOCKET]; /* arbitrary... watch this */
1834 if(ntree==NULL) return;
1836 stack+= gnode->stack_index;
1838 for(node= ntree->nodes.first; node; node= node->next) {
1839 if(node->typeinfo->execfunc) {
1840 group_node_get_stack(node, stack, nsin, nsout, in, out);
1842 /* for groups, only execute outputs for edited group */
1843 if(node->typeinfo->nclass==NODE_CLASS_OUTPUT) {
1844 if(gnode->flag & NODE_GROUP_EDIT)
1845 if(node->flag & NODE_DO_OUTPUT)
1846 node->typeinfo->execfunc(data, node, nsin, nsout);
1849 node->typeinfo->execfunc(data, node, nsin, nsout);
1853 /* free internal group output nodes */
1854 if(ntree->type==NTREE_COMPOSIT) {
1855 for(node= ntree->nodes.first; node; node= node->next) {
1856 if(node->typeinfo->execfunc) {
1859 for(sock= node->outputs.first; sock; sock= sock->next) {
1861 bNodeStack *ns= stack + sock->stack_index;
1863 free_compbuf(ns->data);
1873 /* recursively called for groups */
1874 /* we set all trees on own local indices, but put a total counter
1875 in the groups, so each instance of a group has own stack */
1876 static int ntree_begin_exec_tree(bNodeTree *ntree)
1880 int index= 0, index_in= 0, index_out= 0;
1882 if((ntree->init & NTREE_TYPE_INIT)==0)
1883 ntreeInitTypes(ntree);
1885 /* create indices for stack, check preview */
1886 for(node= ntree->nodes.first; node; node= node->next) {
1888 for(sock= node->inputs.first; sock; sock= sock->next) {
1890 sock->stack_index_ext= index_in++;
1893 for(sock= node->outputs.first; sock; sock= sock->next) {
1894 sock->stack_index= index++;
1896 sock->stack_index_ext= index_out++;
1899 if(node->type==NODE_GROUP) {
1901 node->stack_index= index;
1902 index+= ntree_begin_exec_tree((bNodeTree *)node->id);
1910 /* copy socket compbufs to stack, initialize usage of curve nodes */
1911 static void composit_begin_exec(bNodeTree *ntree, int is_group)
1916 for(node= ntree->nodes.first; node; node= node->next) {
1918 /* initialize needed for groups */
1922 for(sock= node->outputs.first; sock; sock= sock->next) {
1923 bNodeStack *ns= ntree->stack + sock->stack_index;
1926 ns->data= sock->ns.data;
1927 sock->ns.data= NULL;
1931 /* cannot initialize them while using in threads */
1932 if(ELEM4(node->type, CMP_NODE_TIME, CMP_NODE_CURVE_VEC, CMP_NODE_CURVE_RGB, CMP_NODE_HUECORRECT)) {
1933 curvemapping_initialize(node->storage);
1934 if(node->type==CMP_NODE_CURVE_RGB)
1935 curvemapping_premultiply(node->storage, 0);
1937 if(node->type==NODE_GROUP)
1938 composit_begin_exec((bNodeTree *)node->id, 1);
1943 /* copy stack compbufs to sockets */
1944 static void composit_end_exec(bNodeTree *ntree, int is_group)
1946 extern void print_compbuf(char *str, struct CompBuf *cbuf);
1951 for(node= ntree->nodes.first; node; node= node->next) {
1955 for(sock= node->outputs.first; sock; sock= sock->next) {
1956 ns= ntree->stack + sock->stack_index;
1958 sock->ns.data= ns->data;
1963 if(node->type==CMP_NODE_CURVE_RGB)
1964 curvemapping_premultiply(node->storage, 1);
1966 if(node->type==NODE_GROUP)
1967 composit_end_exec((bNodeTree *)node->id, 1);
1973 /* internally, group buffers are not stored */
1974 for(ns= ntree->stack, a=0; a<ntree->stacksize; a++, ns++) {
1976 printf("freed leftover buffer from stack\n");
1977 free_compbuf(ns->data);
1984 static void group_tag_used_outputs(bNode *gnode, bNodeStack *stack)
1986 bNodeTree *ntree= (bNodeTree *)gnode->id;
1989 stack+= gnode->stack_index;
1991 for(node= ntree->nodes.first; node; node= node->next) {
1992 if(node->typeinfo->execfunc) {
1995 for(sock= node->inputs.first; sock; sock= sock->next) {
1998 bNodeStack *ns= stack + sock->link->fromsock->stack_index;
2000 ns->sockettype= sock->link->fromsock->type;
2003 sock->ns.sockettype= sock->type;
2010 /* notes below are ancient! (ton) */
2011 /* stack indices make sure all nodes only write in allocated data, for making it thread safe */
2012 /* only root tree gets the stack, to enable instances to have own stack entries */
2013 /* per tree (and per group) unique indices are created */
2014 /* the index_ext we need to be able to map from groups to the group-node own stack */
2016 typedef struct bNodeThreadStack {
2017 struct bNodeThreadStack *next, *prev;
2022 static bNodeThreadStack *ntreeGetThreadStack(bNodeTree *ntree, int thread)
2024 ListBase *lb= &ntree->threadstack[thread];
2025 bNodeThreadStack *nts;
2027 for(nts=lb->first; nts; nts=nts->next) {
2033 nts= MEM_callocN(sizeof(bNodeThreadStack), "bNodeThreadStack");
2034 nts->stack= MEM_dupallocN(ntree->stack);
2036 BLI_addtail(lb, nts);
2041 static void ntreeReleaseThreadStack(bNodeThreadStack *nts)
2046 /* free texture delegates */
2047 static void tex_end_exec(bNodeTree *ntree)
2049 bNodeThreadStack *nts;
2053 if(ntree->threadstack)
2054 for(th=0; th<BLENDER_MAX_THREADS; th++)
2055 for(nts=ntree->threadstack[th].first; nts; nts=nts->next)
2056 for(ns= nts->stack, a=0; a<ntree->stacksize; a++, ns++)
2058 MEM_freeN(ns->data);
2062 void ntreeBeginExecTree(bNodeTree *ntree)
2064 /* let's make it sure */
2065 if(ntree->init & NTREE_EXEC_INIT)
2068 /* allocate the thread stack listbase array */
2069 if(ntree->type!=NTREE_COMPOSIT)
2070 ntree->threadstack= MEM_callocN(BLENDER_MAX_THREADS*sizeof(ListBase), "thread stack array");
2072 /* goes recursive over all groups */
2073 ntree->stacksize= ntree_begin_exec_tree(ntree);
2075 if(ntree->stacksize) {
2080 /* allocate the base stack */
2081 ns=ntree->stack= MEM_callocN(ntree->stacksize*sizeof(bNodeStack), "node stack");
2083 /* tag inputs, the get_stack() gives own socket stackdata if not in use */
2084 for(a=0; a<ntree->stacksize; a++, ns++) ns->hasinput= 1;
2086 /* tag used outputs, so we know when we can skip operations */
2087 for(node= ntree->nodes.first; node; node= node->next) {
2090 /* composite has own need_exec tag handling */
2091 if(ntree->type!=NTREE_COMPOSIT)
2094 for(sock= node->inputs.first; sock; sock= sock->next) {
2096 ns= ntree->stack + sock->link->fromsock->stack_index;
2098 ns->sockettype= sock->link->fromsock->type;
2101 sock->ns.sockettype= sock->type;
2104 bNodeLink *link= sock->link;
2105 /* this is the test for a cyclic case */
2106 if(link->fromnode && link->tonode) {
2107 if(link->fromnode->level >= link->tonode->level && link->tonode->level!=0xFFF);
2115 if(node->type==NODE_GROUP && node->id)
2116 group_tag_used_outputs(node, ntree->stack);
2120 if(ntree->type==NTREE_COMPOSIT)
2121 composit_begin_exec(ntree, 0);
2124 ntree->init |= NTREE_EXEC_INIT;
2127 void ntreeEndExecTree(bNodeTree *ntree)
2130 if(ntree->init & NTREE_EXEC_INIT) {
2131 bNodeThreadStack *nts;
2134 /* another callback candidate! */
2135 if(ntree->type==NTREE_COMPOSIT)
2136 composit_end_exec(ntree, 0);
2137 else if(ntree->type==NTREE_TEXTURE)
2138 tex_end_exec(ntree);
2141 MEM_freeN(ntree->stack);
2145 if(ntree->threadstack) {
2146 for(a=0; a<BLENDER_MAX_THREADS; a++) {
2147 for(nts=ntree->threadstack[a].first; nts; nts=nts->next)
2148 if (nts->stack) MEM_freeN(nts->stack);
2149 BLI_freelistN(&ntree->threadstack[a]);
2152 MEM_freeN(ntree->threadstack);
2153 ntree->threadstack= NULL;
2156 ntree->init &= ~NTREE_EXEC_INIT;
2160 static void node_get_stack(bNode *node, bNodeStack *stack, bNodeStack **in, bNodeStack **out)
2164 /* build pointer stack */
2165 for(sock= node->inputs.first; sock; sock= sock->next) {
2167 *(in++)= stack + sock->link->fromsock->stack_index;
2172 for(sock= node->outputs.first; sock; sock= sock->next) {
2173 *(out++)= stack + sock->stack_index;
2177 /* nodes are presorted, so exec is in order of list */
2178 void ntreeExecTree(bNodeTree *ntree, void *callerdata, int thread)
2181 bNodeStack *nsin[MAX_SOCKET]; /* arbitrary... watch this */
2182 bNodeStack *nsout[MAX_SOCKET]; /* arbitrary... watch this */
2184 bNodeThreadStack *nts = NULL;
2186 /* only when initialized */
2187 if((ntree->init & NTREE_EXEC_INIT)==0)
2188 ntreeBeginExecTree(ntree);
2190 /* composite does 1 node per thread, so no multiple stacks needed */
2191 if(ntree->type==NTREE_COMPOSIT) {
2192 stack= ntree->stack;
2195 nts= ntreeGetThreadStack(ntree, thread);
2199 for(node= ntree->nodes.first; node; node= node->next) {
2200 if(node->need_exec) {
2201 if(node->typeinfo->execfunc) {
2202 node_get_stack(node, stack, nsin, nsout);
2203 node->typeinfo->execfunc(callerdata, node, nsin, nsout);
2205 else if(node->type==NODE_GROUP && node->id) {
2206 node_get_stack(node, stack, nsin, nsout);
2207 node_group_execute(stack, callerdata, node, nsin, nsout);
2213 ntreeReleaseThreadStack(nts);
2217 /* ***************************** threaded version for execute composite nodes ************* */
2218 /* these are nodes without input, only giving values */
2219 /* or nodes with only value inputs */
2220 static int node_only_value(bNode *node)
2224 if(ELEM3(node->type, CMP_NODE_TIME, CMP_NODE_VALUE, CMP_NODE_RGB))
2227 /* doing this for all node types goes wrong. memory free errors */
2228 if(node->inputs.first && node->type==CMP_NODE_MAP_VALUE) {
2230 for(sock= node->inputs.first; sock; sock= sock->next) {
2232 retval &= node_only_value(sock->link->fromnode);
2240 /* not changing info, for thread callback */
2241 typedef struct ThreadData {
2246 static void *exec_composite_node(void *node_v)
2248 bNodeStack *nsin[MAX_SOCKET]; /* arbitrary... watch this */
2249 bNodeStack *nsout[MAX_SOCKET]; /* arbitrary... watch this */
2250 bNode *node= node_v;
2251 ThreadData *thd= (ThreadData *)node->threaddata;
2253 node_get_stack(node, thd->stack, nsin, nsout);
2255 if((node->flag & NODE_MUTED) && (!node_only_value(node))) {
2256 /* viewers we execute, for feedback to user */
2257 if(ELEM(node->type, CMP_NODE_VIEWER, CMP_NODE_SPLITVIEWER))
2258 node->typeinfo->execfunc(thd->rd, node, nsin, nsout);
2260 node_compo_pass_on(node, nsin, nsout);
2262 else if(node->typeinfo->execfunc) {
2263 node->typeinfo->execfunc(thd->rd, node, nsin, nsout);
2265 else if(node->type==NODE_GROUP && node->id) {
2266 node_group_execute(thd->stack, thd->rd, node, nsin, nsout);
2269 node->exec |= NODE_READY;
2273 /* return total of executable nodes, for timecursor */
2274 /* only compositor uses it */
2275 static int setExecutableNodes(bNodeTree *ntree, ThreadData *thd)
2277 bNodeStack *nsin[MAX_SOCKET]; /* arbitrary... watch this */
2278 bNodeStack *nsout[MAX_SOCKET]; /* arbitrary... watch this */
2281 int totnode= 0, group_edit= 0;
2283 /* note; do not add a dependency sort here, the stack was created already */
2285 /* if we are in group edit, viewer nodes get skipped when group has viewer */
2286 for(node= ntree->nodes.first; node; node= node->next)
2287 if(node->type==NODE_GROUP && (node->flag & NODE_GROUP_EDIT))
2288 if(ntreeHasType((bNodeTree *)node->id, CMP_NODE_VIEWER))
2291 for(node= ntree->nodes.first; node; node= node->next) {
2294 node_get_stack(node, thd->stack, nsin, nsout);
2296 /* test the outputs */
2297 /* skip value-only nodes (should be in type!) */
2298 if(!node_only_value(node)) {
2299 for(a=0, sock= node->outputs.first; sock; sock= sock->next, a++) {
2300 if(nsout[a]->data==NULL && nsout[a]->hasoutput) {
2307 /* test the inputs */
2308 for(a=0, sock= node->inputs.first; sock; sock= sock->next, a++) {
2309 /* skip viewer nodes in bg render or group edit */
2310 if( ELEM(node->type, CMP_NODE_VIEWER, CMP_NODE_SPLITVIEWER) && (G.background || group_edit))
2312 /* is sock in use? */
2313 else if(sock->link) {
2314 bNodeLink *link= sock->link;
2316 /* this is the test for a cyclic case */
2317 if(link->fromnode==NULL || link->tonode==NULL);
2318 else if(link->fromnode->level >= link->tonode->level && link->tonode->level!=0xFFF) {
2319 if(link->fromnode->need_exec) {
2326 printf("Node %s skipped, cyclic dependency\n", node->name);
2331 if(node->need_exec) {
2333 /* free output buffers */
2334 for(a=0, sock= node->outputs.first; sock; sock= sock->next, a++) {
2335 if(nsout[a]->data) {
2336 free_compbuf(nsout[a]->data);
2337 nsout[a]->data= NULL;
2341 /* printf("node needs exec %s\n", node->name); */
2343 /* tag for getExecutableNode() */
2347 /* tag for getExecutableNode() */
2348 node->exec= NODE_READY|NODE_FINISHED|NODE_SKIPPED;
2353 /* last step: set the stack values for only-value nodes */
2354 /* just does all now, compared to a full buffer exec this is nothing */
2356 for(node= ntree->nodes.first; node; node= node->next) {
2357 if(node->need_exec==0 && node_only_value(node)) {
2358 if(node->typeinfo->execfunc) {
2359 node_get_stack(node, thd->stack, nsin, nsout);
2360 node->typeinfo->execfunc(thd->rd, node, nsin, nsout);
2369 /* while executing tree, free buffers from nodes that are not needed anymore */
2370 static void freeExecutableNode(bNodeTree *ntree)
2372 /* node outputs can be freed when:
2373 - not a render result or image node
2374 - when node outputs go to nodes all being set NODE_FINISHED
2379 /* set exec flag for finished nodes that might need freed */
2380 for(node= ntree->nodes.first; node; node= node->next) {
2381 if(node->type!=CMP_NODE_R_LAYERS)
2382 if(node->exec & NODE_FINISHED)
2383 node->exec |= NODE_FREEBUFS;
2385 /* clear this flag for input links that are not done yet */
2386 for(node= ntree->nodes.first; node; node= node->next) {
2387 if((node->exec & NODE_FINISHED)==0) {
2388 for(sock= node->inputs.first; sock; sock= sock->next)
2390 sock->link->fromnode->exec &= ~NODE_FREEBUFS;
2393 /* now we can free buffers */
2394 for(node= ntree->nodes.first; node; node= node->next) {
2395 if(node->exec & NODE_FREEBUFS) {
2396 for(sock= node->outputs.first; sock; sock= sock->next) {
2397 bNodeStack *ns= ntree->stack + sock->stack_index;
2399 free_compbuf(ns->data);
2401 // printf("freed buf node %s \n", node->name);
2408 static bNode *getExecutableNode(bNodeTree *ntree)
2413 for(node= ntree->nodes.first; node; node= node->next) {
2416 /* input sockets should be ready */
2417 for(sock= node->inputs.first; sock; sock= sock->next) {
2419 if((sock->link->fromnode->exec & NODE_READY)==0)
2430 /* optimized tree execute test for compositing */
2431 void ntreeCompositExecTree(bNodeTree *ntree, RenderData *rd, int do_preview)
2436 int totnode, rendering= 1;
2438 if(ntree==NULL) return;
2441 ntreeInitPreview(ntree, 0, 0);
2443 ntreeBeginExecTree(ntree);
2445 /* prevent unlucky accidents */
2447 rd->scemode &= ~R_COMP_CROP;
2449 /* setup callerdata for thread callback */
2451 thdata.stack= ntree->stack;
2453 /* fixed seed, for example noise texture */
2454 BLI_srandom(rd->cfra);
2456 /* sets need_exec tags in nodes */
2457 totnode= setExecutableNodes(ntree, &thdata);
2459 BLI_init_threads(&threads, exec_composite_node, rd->threads);
2463 if(BLI_available_threads(&threads)) {
2464 node= getExecutableNode(ntree);
2467 if(ntree->timecursor)
2468 ntree->timecursor(ntree->tch, totnode);
2469 if(ntree->stats_draw) {
2471 sprintf(str, "Compositing %d %s", totnode, node->name);
2472 ntree->stats_draw(ntree->sdh, str);
2476 node->threaddata = &thdata;
2477 node->exec= NODE_PROCESSING;
2478 BLI_insert_thread(&threads, node);
2488 if(ntree->test_break && ntree->test_break(ntree->tbh)) {
2489 for(node= ntree->nodes.first; node; node= node->next)
2490 node->exec |= NODE_READY;
2493 /* check for ready ones, and if we need to continue */
2494 for(node= ntree->nodes.first; node; node= node->next) {
2495 if(node->exec & NODE_READY) {
2496 if((node->exec & NODE_FINISHED)==0) {
2497 BLI_remove_thread(&threads, node); /* this waits for running thread to finish btw */
2498 node->exec |= NODE_FINISHED;
2500 /* freeing unused buffers */
2501 if(rd->scemode & R_COMP_FREE)
2502 freeExecutableNode(ntree);
2509 BLI_end_threads(&threads);
2511 ntreeEndExecTree(ntree);
2515 /* ********** copy composite tree entirely, to allow threaded exec ******************* */
2516 /* ***************** do NOT execute this in a thread! ****************** */
2518 /* returns localized composite tree for execution in threads */
2519 /* local tree then owns all compbufs */
2520 bNodeTree *ntreeLocalize(bNodeTree *ntree)
2522 bNodeTree *ltree= ntreeCopyTree(ntree, 0);
2526 /* move over the compbufs */
2527 /* right after ntreeCopyTree() oldsock pointers are valid */
2528 for(node= ntree->nodes.first; node; node= node->next) {
2530 /* store new_node pointer to original */
2531 node->new_node->new_node= node;
2532 /* ensure new user input gets handled ok */
2535 if(ELEM(node->type, CMP_NODE_VIEWER, CMP_NODE_SPLITVIEWER)) {
2537 if(node->flag & NODE_DO_OUTPUT)
2538 node->new_node->id= (ID *)BKE_image_copy((Image *)node->id);
2540 node->new_node->id= NULL;
2544 for(sock= node->outputs.first; sock; sock= sock->next) {
2546 sock->new_sock->ns.data= sock->ns.data;
2547 sock->ns.data= NULL;
2548 sock->new_sock->new_sock= sock;
2555 static int node_exists(bNodeTree *ntree, bNode *testnode)
2557 bNode *node= ntree->nodes.first;
2558 for(; node; node= node->next)
2564 static int outsocket_exists(bNode *node, bNodeSocket *testsock)
2566 bNodeSocket *sock= node->outputs.first;
2567 for(; sock; sock= sock->next)
2574 /* sync local composite with real tree */
2575 /* local composite is supposed to be running, be careful moving previews! */
2576 void ntreeLocalSync(bNodeTree *localtree, bNodeTree *ntree)
2580 /* move over the compbufs and previews */
2581 for(lnode= localtree->nodes.first; lnode; lnode= lnode->next) {
2582 if( (lnode->exec & NODE_READY) && !(lnode->exec & NODE_SKIPPED) ) {
2583 if(node_exists(ntree, lnode->new_node)) {
2585 if(lnode->preview && lnode->preview->rect) {
2586 node_free_preview(lnode->new_node);
2587 lnode->new_node->preview= lnode->preview;
2588 lnode->preview= NULL;
2595 /* merge local tree results back, and free local tree */
2596 /* we have to assume the editor already changed completely */
2597 void ntreeLocalMerge(bNodeTree *localtree, bNodeTree *ntree)
2602 /* move over the compbufs and previews */
2603 for(lnode= localtree->nodes.first; lnode; lnode= lnode->next) {
2604 if(node_exists(ntree, lnode->new_node)) {
2606 if(lnode->preview && lnode->preview->rect) {
2607 node_free_preview(lnode->new_node);
2608 lnode->new_node->preview= lnode->preview;
2609 lnode->preview= NULL;
2612 if(ELEM(lnode->type, CMP_NODE_VIEWER, CMP_NODE_SPLITVIEWER)) {
2613 if(lnode->id && (lnode->flag & NODE_DO_OUTPUT)) {
2614 /* image_merge does sanity check for pointers */
2615 BKE_image_merge((Image *)lnode->new_node->id, (Image *)lnode->id);
2619 for(lsock= lnode->outputs.first; lsock; lsock= lsock->next) {
2620 if(outsocket_exists(lnode->new_node, lsock->new_sock)) {
2621 lsock->new_sock->ns.data= lsock->ns.data;
2622 lsock->ns.data= NULL;
2623 lsock->new_sock= NULL;
2628 ntreeFreeTree(localtree);
2629 MEM_freeN(localtree);
2632 /* *********************************************** */
2634 /* GPU material from shader nodes */
2636 static void gpu_from_node_stack(ListBase *sockets, bNodeStack **ns, GPUNodeStack *gs)
2641 for (sock=sockets->first, i=0; sock; sock=sock->next, i++) {
2642 memset(&gs[i], 0, sizeof(gs[i]));
2644 QUATCOPY(gs[i].vec, ns[i]->vec);
2645 gs[i].link= ns[i]->data;
2647 if (sock->type == SOCK_VALUE)
2648 gs[i].type= GPU_FLOAT;
2649 else if (sock->type == SOCK_VECTOR)
2650 gs[i].type= GPU_VEC3;
2651 else if (sock->type == SOCK_RGBA)
2652 gs[i].type= GPU_VEC4;
2654 gs[i].type= GPU_NONE;
2657 gs[i].hasinput= ns[i]->hasinput && ns[i]->data;
2658 gs[i].hasoutput= ns[i]->hasinput && ns[i]->data;
2659 gs[i].sockettype= ns[i]->sockettype;
2662 gs[i].type= GPU_NONE;
2665 static void data_from_gpu_stack(ListBase *sockets, bNodeStack **ns, GPUNodeStack *gs)
2670 for (sock=sockets->first, i=0; sock; sock=sock->next, i++) {
2671 ns[i]->data= gs[i].link;
2672 ns[i]->hasinput= gs[i].hasinput && gs[i].link;
2673 ns[i]->hasoutput= gs[i].hasoutput;
2674 ns[i]->sockettype= gs[i].sockettype;
2678 static void gpu_node_group_execute(bNodeStack *stack, GPUMaterial *mat, bNode *gnode, bNodeStack **in, bNodeStack **out)
2681 bNodeTree *ntree= (bNodeTree *)gnode->id;
2682 bNodeStack *nsin[MAX_SOCKET]; /* arbitrary... watch this */
2683 bNodeStack *nsout[MAX_SOCKET]; /* arbitrary... watch this */
2684 GPUNodeStack gpuin[MAX_SOCKET+1], gpuout[MAX_SOCKET+1];
2687 if(ntree==NULL) return;
2689 stack+= gnode->stack_index;
2691 for(node= ntree->nodes.first; node; node= node->next) {
2692 if(node->typeinfo->gpufunc) {
2693 group_node_get_stack(node, stack, nsin, nsout, in, out);
2697 /* for groups, only execute outputs for edited group */
2698 if(node->typeinfo->nclass==NODE_CLASS_OUTPUT) {
2699 if(gnode->flag & NODE_GROUP_EDIT)
2700 if(node->flag & NODE_DO_OUTPUT)
2707 gpu_from_node_stack(&node->inputs, nsin, gpuin);
2708 gpu_from_node_stack(&node->outputs, nsout, gpuout);
2709 if(node->typeinfo->gpufunc(mat, node, gpuin, gpuout))
2710 data_from_gpu_stack(&node->outputs, nsout, gpuout);
2716 void ntreeGPUMaterialNodes(bNodeTree *ntree, GPUMaterial *mat)
2720 bNodeStack *nsin[MAX_SOCKET]; /* arbitrary... watch this */
2721 bNodeStack *nsout[MAX_SOCKET]; /* arbitrary... watch this */
2722 GPUNodeStack gpuin[MAX_SOCKET+1], gpuout[MAX_SOCKET+1];
2724 if((ntree->init & NTREE_EXEC_INIT)==0)
2725 ntreeBeginExecTree(ntree);
2727 stack= ntree->stack;
2729 for(node= ntree->nodes.first; node; node= node->next) {
2730 if(node->typeinfo->gpufunc) {
2731 node_get_stack(node, stack, nsin, nsout);
2732 gpu_from_node_stack(&node->inputs, nsin, gpuin);
2733 gpu_from_node_stack(&node->outputs, nsout, gpuout);
2734 if(node->typeinfo->gpufunc(mat, node, gpuin, gpuout))
2735 data_from_gpu_stack(&node->outputs, nsout, gpuout);
2737 else if(node->type==NODE_GROUP && node->id) {
2738 node_get_stack(node, stack, nsin, nsout);
2739 gpu_node_group_execute(stack, mat, node, nsin, nsout);
2743 ntreeEndExecTree(ntree);
2746 /* **************** call to switch lamploop for material node ************ */
2748 void (*node_shader_lamp_loop)(struct ShadeInput *, struct ShadeResult *);
2750 void set_node_shader_lamp_loop(void (*lamp_loop_func)(ShadeInput *, ShadeResult *))
2752 node_shader_lamp_loop= lamp_loop_func;
2755 /* clumsy checking... should do dynamic outputs once */
2756 static void force_hidden_passes(bNode *node, int passflag)
2760 for(sock= node->outputs.first; sock; sock= sock->next)
2761 sock->flag &= ~SOCK_UNAVAIL;
2763 sock= BLI_findlink(&node->outputs, RRES_OUT_Z);
2764 if(!(passflag & SCE_PASS_Z)) sock->flag |= SOCK_UNAVAIL;
2765 sock= BLI_findlink(&node->outputs, RRES_OUT_NORMAL);
2766 if(!(passflag & SCE_PASS_NORMAL)) sock->flag |= SOCK_UNAVAIL;
2767 sock= BLI_findlink(&node->outputs, RRES_OUT_VEC);
2768 if(!(passflag & SCE_PASS_VECTOR)) sock->flag |= SOCK_UNAVAIL;
2769 sock= BLI_findlink(&node->outputs, RRES_OUT_UV);
2770 if(!(passflag & SCE_PASS_UV)) sock->flag |= SOCK_UNAVAIL;
2771 sock= BLI_findlink(&node->outputs, RRES_OUT_RGBA);
2772 if(!(passflag & SCE_PASS_RGBA)) sock->flag |= SOCK_UNAVAIL;
2773 sock= BLI_findlink(&node->outputs, RRES_OUT_DIFF);
2774 if(!(passflag & SCE_PASS_DIFFUSE)) sock->flag |= SOCK_UNAVAIL;
2775 sock= BLI_findlink(&node->outputs, RRES_OUT_SPEC);
2776 if(!(passflag & SCE_PASS_SPEC)) sock->flag |= SOCK_UNAVAIL;
2777 sock= BLI_findlink(&node->outputs, RRES_OUT_SHADOW);
2778 if(!(passflag & SCE_PASS_SHADOW)) sock->flag |= SOCK_UNAVAIL;
2779 sock= BLI_findlink(&node->outputs, RRES_OUT_AO);
2780 if(!(passflag & SCE_PASS_AO)) sock->flag |= SOCK_UNAVAIL;
2781 sock= BLI_findlink(&node->outputs, RRES_OUT_REFLECT);
2782 if(!(passflag & SCE_PASS_REFLECT)) sock->flag |= SOCK_UNAVAIL;
2783 sock= BLI_findlink(&node->outputs, RRES_OUT_REFRACT);
2784 if(!(passflag & SCE_PASS_REFRACT)) sock->flag |= SOCK_UNAVAIL;
2785 sock= BLI_findlink(&node->outputs, RRES_OUT_INDIRECT);
2786 if(!(passflag & SCE_PASS_INDIRECT)) sock->flag |= SOCK_UNAVAIL;
2787 sock= BLI_findlink(&node->outputs, RRES_OUT_INDEXOB);
2788 if(!(passflag & SCE_PASS_INDEXOB)) sock->flag |= SOCK_UNAVAIL;
2789 sock= BLI_findlink(&node->outputs, RRES_OUT_MIST);
2790 if(!(passflag & SCE_PASS_MIST)) sock->flag |= SOCK_UNAVAIL;
2791 sock= BLI_findlink(&node->outputs, RRES_OUT_EMIT);
2792 if(!(passflag & SCE_PASS_EMIT)) sock->flag |= SOCK_UNAVAIL;
2793 sock= BLI_findlink(&node->outputs, RRES_OUT_ENV);
2794 if(!(passflag & SCE_PASS_ENVIRONMENT)) sock->flag |= SOCK_UNAVAIL;
2798 /* based on rules, force sockets hidden always */
2799 void ntreeCompositForceHidden(bNodeTree *ntree, Scene *curscene)
2803 if(ntree==NULL) return;
2805 for(node= ntree->nodes.first; node; node= node->next) {
2806 if( node->type==CMP_NODE_R_LAYERS) {
2807 Scene *sce= node->id?(Scene *)node->id:curscene;
2808 SceneRenderLayer *srl= BLI_findlink(&sce->r.layers, node->custom1);
2810 force_hidden_passes(node, srl->passflag);
2812 else if( node->type==CMP_NODE_IMAGE) {
2813 Image *ima= (Image *)node->id;
2816 ImageUser *iuser= node->storage;
2817 RenderLayer *rl= BLI_findlink(&ima->rr->layers, iuser->layer);
2819 force_hidden_passes(node, rl->passflag);
2821 force_hidden_passes(node, 0);
2823 else if(ima->type!=IMA_TYPE_MULTILAYER) { /* if ->rr not yet read we keep inputs */
2824 force_hidden_passes(node, RRES_OUT_Z);
2827 force_hidden_passes(node, 0);
2830 force_hidden_passes(node, 0);
2836 /* called from render pipeline, to tag render input and output */
2837 /* need to do all scenes, to prevent errors when you re-render 1 scene */
2838 void ntreeCompositTagRender(Scene *curscene)
2842 for(sce= G.main->scene.first; sce; sce= sce->id.next) {
2846 for(node= sce->nodetree->nodes.first; node; node= node->next) {
2847 if(node->id==(ID *)curscene || node->type==CMP_NODE_COMPOSITE)
2848 NodeTagChanged(sce->nodetree, node);
2854 static int node_animation_properties(bNodeTree *ntree, bNode *node)
2862 /* check to see if any of the node's properties have fcurves */
2863 RNA_pointer_create((ID *)ntree, &RNA_Node, node, &ptr);
2864 lb = RNA_struct_defined_properties(ptr.type);
2866 for (link=lb->first; link; link=link->next) {
2867 int driven, len=1, index;
2868 prop = (PropertyRNA *)link;
2870 if (RNA_property_array_check(&ptr, prop))
2871 len = RNA_property_array_length(&ptr, prop);
2873 for (index=0; index<len; index++) {
2874 if (rna_get_fcurve(&ptr, prop, index, NULL, &driven)) {
2875 NodeTagChanged(ntree, node);
2881 /* now check node sockets */
2882 for (sock = node->inputs.first; sock; sock=sock->next) {
2883 int driven, len=1, index;
2885 RNA_pointer_create((ID *)ntree, &RNA_NodeSocket, sock, &ptr);
2886 prop = RNA_struct_find_property(&ptr, "default_value");
2888 if (RNA_property_array_check(&ptr, prop))
2889 len = RNA_property_array_length(&ptr, prop);
2891 for (index=0; index<len; index++) {
2892 if (rna_get_fcurve(&ptr, prop, index, NULL, &driven)) {
2893 NodeTagChanged(ntree, node);
2902 /* tags nodes that have animation capabilities */
2903 int ntreeCompositTagAnimated(bNodeTree *ntree)
2908 if(ntree==NULL) return 0;
2910 for(node= ntree->nodes.first; node; node= node->next) {
2912 tagged = node_animation_properties(ntree, node);
2914 /* otherwise always tag these node types */
2915 if(node->type==CMP_NODE_IMAGE) {
2916 Image *ima= (Image *)node->id;
2917 if(ima && ELEM(ima->source, IMA_SRC_MOVIE, IMA_SRC_SEQUENCE)) {
2918 NodeTagChanged(ntree, node);
2922 else if(node->type==CMP_NODE_TIME) {
2923 NodeTagChanged(ntree, node);
2926 else if(node->type==CMP_NODE_R_LAYERS) {
2927 NodeTagChanged(ntree, node);
2930 else if(node->type==NODE_GROUP) {
2931 if( ntreeCompositTagAnimated((bNodeTree *)node->id) ) {
2932 NodeTagChanged(ntree, node);
2941 /* called from image window preview */
2942 void ntreeCompositTagGenerators(bNodeTree *ntree)
2946 if(ntree==NULL) return;
2948 for(node= ntree->nodes.first; node; node= node->next) {
2949 if( ELEM(node->type, CMP_NODE_R_LAYERS, CMP_NODE_IMAGE))
2950 NodeTagChanged(ntree, node);
2954 int ntreeTexTagAnimated(bNodeTree *ntree)
2958 if(ntree==NULL) return 0;
2960 for(node= ntree->nodes.first; node; node= node->next) {
2961 if(node->type==TEX_NODE_CURVE_TIME) {
2962 NodeTagChanged(ntree, node);
2965 else if(node->type==NODE_GROUP) {
2966 if( ntreeTexTagAnimated((bNodeTree *)node->id) ) {
2975 /* ************* node definition init ********** */
2977 static bNodeType *is_nodetype_registered(ListBase *typelist, int type, ID *id)
2979 bNodeType *ntype= typelist->first;
2981 for(;ntype; ntype= ntype->next )
2982 if(ntype->type==type && ntype->id==id)
2988 /* type can be from a static array, we make copy for duplicate types (like group) */
2989 void nodeRegisterType(ListBase *typelist, const bNodeType *ntype)
2991 bNodeType *found= is_nodetype_registered(typelist, ntype->type, ntype->id);
2994 bNodeType *ntypen= MEM_callocN(sizeof(bNodeType), "node type");
2996 BLI_addtail(typelist, ntypen);
3000 static void registerCompositNodes(ListBase *ntypelist)
3002 nodeRegisterType(ntypelist, &node_group_typeinfo);
3003 nodeRegisterType(ntypelist, &cmp_node_rlayers);
3004 nodeRegisterType(ntypelist, &cmp_node_image);
3005 nodeRegisterType(ntypelist, &cmp_node_texture);
3006 nodeRegisterType(ntypelist, &cmp_node_value);
3007 nodeRegisterType(ntypelist, &cmp_node_rgb);
3008 nodeRegisterType(ntypelist, &cmp_node_curve_time);
3010 nodeRegisterType(ntypelist, &cmp_node_composite);
3011 nodeRegisterType(ntypelist, &cmp_node_viewer);
3012 nodeRegisterType(ntypelist, &cmp_node_splitviewer);
3013 nodeRegisterType(ntypelist, &cmp_node_output_file);
3014 nodeRegisterType(ntypelist, &cmp_node_view_levels);
3016 nodeRegisterType(ntypelist, &cmp_node_curve_rgb);
3017 nodeRegisterType(ntypelist, &cmp_node_mix_rgb);
3018 nodeRegisterType(ntypelist, &cmp_node_hue_sat);
3019 nodeRegisterType(ntypelist, &cmp_node_brightcontrast);
3020 nodeRegisterType(ntypelist, &cmp_node_gamma);
3021 nodeRegisterType(ntypelist, &cmp_node_invert);
3022 nodeRegisterType(ntypelist, &cmp_node_alphaover);
3023 nodeRegisterType(ntypelist, &cmp_node_zcombine);
3024 nodeRegisterType(ntypelist, &cmp_node_colorbalance);
3025 nodeRegisterType(ntypelist, &cmp_node_huecorrect);