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_node_types.h"
35 #include "DNA_material_types.h"
36 #include "DNA_scene_types.h"
38 #include "BKE_blender.h"
39 #include "BKE_colortools.h"
40 #include "BKE_global.h"
41 #include "BKE_library.h"
44 #include "BKE_texture.h"
45 #include "BKE_utildefines.h"
47 #include "BLI_arithb.h"
48 #include "BLI_blenlib.h"
50 #include "MEM_guardedalloc.h"
51 #include "IMB_imbuf.h"
53 /* not very important, but the stack solver likes to know a maximum */
56 #pragma mark /* ************** Type stuff ********** */
58 static bNodeType *node_get_type(bNodeTree *ntree, int type, bNodeTree *ngroup)
60 if(type==NODE_GROUP) {
61 if(ngroup && GS(ngroup->id.name)==ID_NT) {
62 return ngroup->owntype;
67 bNodeType **typedefs= ntree->alltypes;
69 while( *typedefs && (*typedefs)->type!=type)
76 void ntreeInitTypes(bNodeTree *ntree)
80 if(ntree->type==NTREE_SHADER)
81 ntree->alltypes= node_all_shaders;
82 else if(ntree->type==NTREE_COMPOSIT)
83 ntree->alltypes= node_all_composit;
85 ntree->alltypes= NULL;
86 printf("Error: no type definitions for nodes\n");
89 for(node= ntree->nodes.first; node; node= next) {
91 node->typeinfo= node_get_type(ntree, node->type, (bNodeTree *)node->id);
92 if(node->typeinfo==NULL) {
93 printf("Error: Node type %s doesn't exist anymore, removed\n", node->name);
94 nodeFreeNode(ntree, node);
98 ntree->init |= NTREE_TYPE_INIT;
101 /* only used internal... we depend on type definitions! */
102 static bNodeSocket *node_add_socket_type(ListBase *lb, bNodeSocketType *stype)
104 bNodeSocket *sock= MEM_callocN(sizeof(bNodeSocket), "sock");
106 BLI_strncpy(sock->name, stype->name, NODE_MAXSTR);
107 if(stype->limit==0) sock->limit= 0xFFF;
108 else sock->limit= stype->limit;
109 sock->type= stype->type;
111 sock->to_index= stype->own_index;
112 sock->tosock= stype->internsock;
114 sock->ns.vec[0]= stype->val1;
115 sock->ns.vec[1]= stype->val2;
116 sock->ns.vec[2]= stype->val3;
117 sock->ns.vec[3]= stype->val4;
120 BLI_addtail(lb, sock);
125 static void node_rem_socket(bNodeTree *ntree, ListBase *lb, bNodeSocket *sock)
127 bNodeLink *link, *next;
129 for(link= ntree->links.first; link; link= next) {
131 if(link->fromsock==sock || link->tosock==sock) {
132 nodeRemLink(ntree, link);
136 BLI_remlink(lb, sock);
140 static bNodeSocket *verify_socket(ListBase *lb, bNodeSocketType *stype)
144 for(sock= lb->first; sock; sock= sock->next) {
145 /* both indices are zero for non-groups, otherwise it's a unique index */
146 if(sock->to_index==stype->own_index)
147 if(strncmp(sock->name, stype->name, NODE_MAXSTR)==0)
151 sock->type= stype->type; /* in future, read this from tydefs! */
152 if(stype->limit==0) sock->limit= 0xFFF;
153 else sock->limit= stype->limit;
154 sock->tosock= stype->internsock;
156 BLI_remlink(lb, sock);
161 return node_add_socket_type(NULL, stype);
165 static void verify_socket_list(bNodeTree *ntree, ListBase *lb, bNodeSocketType *stype_first)
167 bNodeSocketType *stype;
169 /* no inputs anymore? */
170 if(stype_first==NULL) {
172 node_rem_socket(ntree, lb, lb->first);
175 /* step by step compare */
177 while(stype->type != -1) {
178 stype->sock= verify_socket(lb, stype);
181 /* leftovers are removed */
183 node_rem_socket(ntree, lb, lb->first);
184 /* and we put back the verified sockets */
186 while(stype->type != -1) {
187 BLI_addtail(lb, stype->sock);
193 void nodeVerifyType(bNodeTree *ntree, bNode *node)
195 bNodeType *ntype= node->typeinfo;
198 /* might add some other verify stuff here */
200 verify_socket_list(ntree, &node->inputs, ntype->inputs);
201 verify_socket_list(ntree, &node->outputs, ntype->outputs);
205 void ntreeVerifyTypes(bNodeTree *ntree)
209 if((ntree->init & NTREE_TYPE_INIT)==0)
210 ntreeInitTypes(ntree);
212 /* check inputs and outputs, and remove or insert them */
213 for(node= ntree->nodes.first; node; node= node->next)
214 nodeVerifyType(ntree, node);
218 #pragma mark /* ************** Group stuff ********** */
220 bNodeType node_group_typeinfo= {
221 /* type code */ NODE_GROUP,
223 /* width+range */ 120, 60, 200,
224 /* class+opts */ NODE_CLASS_GROUP, NODE_OPTIONS,
225 /* input sock */ NULL,
226 /* output sock */ NULL,
232 /* tag internal sockets */
233 static void group_tag_internal_sockets(bNodeTree *ngroup)
239 /* clear intern tag, but check already for hidden sockets */
240 for(node= ngroup->nodes.first; node; node= node->next) {
241 for(sock= node->inputs.first; sock; sock= sock->next)
242 sock->intern= sock->flag & SOCK_HIDDEN;
243 for(sock= node->outputs.first; sock; sock= sock->next)
244 sock->intern= sock->flag & SOCK_HIDDEN;
247 for(link= ngroup->links.first; link; link= link->next) {
248 link->fromsock->intern= 1;
249 link->tosock->intern= 1;
252 /* remove link pointer to external links (only happens on create group) */
253 for(node= ngroup->nodes.first; node; node= node->next) {
254 for(sock= node->inputs.first; sock; sock= sock->next)
259 /* set all intern sockets to own_index zero, makes sure that later use won't mixup */
260 for(node= ngroup->nodes.first; node; node= node->next) {
261 for(sock= node->inputs.first; sock; sock= sock->next)
264 for(sock= node->outputs.first; sock; sock= sock->next)
270 /* after editing group, new sockets are zero */
271 /* this routine ensures unique identifiers for zero sockets that are exposed */
272 static void group_verify_own_indices(bNodeTree *ngroup)
277 for(node= ngroup->nodes.first; node; node= node->next) {
278 for(sock= node->inputs.first; sock; sock= sock->next)
279 if(sock->own_index==0 && sock->intern==0)
280 sock->own_index= ++(ngroup->cur_index);
281 for(sock= node->outputs.first; sock; sock= sock->next)
282 if(sock->own_index==0 && sock->intern==0)
283 sock->own_index= ++(ngroup->cur_index);
285 printf("internal index %d\n", ngroup->cur_index);
289 /* nodetrees can be used as groups, so we need typeinfo structs generated */
290 void ntreeMakeOwnType(bNodeTree *ngroup)
294 int totin= 0, totout=0, a;
296 /* tags socket when internal linked */
297 group_tag_internal_sockets(ngroup);
299 /* ensure all sockets have own unique id */
300 group_verify_own_indices(ngroup);
303 for(node= ngroup->nodes.first; node; node= node->next) {
304 if(node->type==NODE_GROUP)
306 for(sock= node->inputs.first; sock; sock= sock->next)
309 for(sock= node->outputs.first; sock; sock= sock->next)
313 /* debug: nodetrees in nodetrees not handled yet */
315 printf("group in group, not supported yet\n");
319 /* free own type struct */
320 if(ngroup->owntype) {
321 if(ngroup->owntype->inputs)
322 MEM_freeN(ngroup->owntype->inputs);
323 if(ngroup->owntype->outputs)
324 MEM_freeN(ngroup->owntype->outputs);
325 MEM_freeN(ngroup->owntype);
328 /* make own type struct */
329 ngroup->owntype= MEM_mallocN(sizeof(bNodeType), "group type");
330 *ngroup->owntype= node_group_typeinfo;
332 /* input type arrays */
334 bNodeSocketType *stype;
335 bNodeSocketType *inputs= MEM_mallocN(sizeof(bNodeSocketType)*(totin+1), "bNodeSocketType");
338 for(node= ngroup->nodes.first; node; node= node->next) {
339 /* nodes are presumed fully verified, stype and socket list are in sync */
340 stype= node->typeinfo->inputs;
341 for(sock= node->inputs.first; sock; sock= sock->next, stype++) {
342 if(sock->intern==0) {
343 /* debug only print */
344 if(stype==NULL || stype->type==-1) printf("group verification error %s\n", ngroup->id.name);
347 inputs[a].own_index= sock->own_index;
348 inputs[a].internsock= sock;
353 inputs[a].type= -1; /* terminator code */
354 ngroup->owntype->inputs= inputs;
357 /* output type arrays */
359 bNodeSocketType *stype;
360 bNodeSocketType *outputs= MEM_mallocN(sizeof(bNodeSocketType)*(totout+1), "bNodeSocketType");
363 for(node= ngroup->nodes.first; node; node= node->next) {
364 /* nodes are presumed fully verified, stype and socket list are in sync */
365 stype= node->typeinfo->outputs;
366 for(sock= node->outputs.first; sock; sock= sock->next, stype++) {
367 if(sock->intern==0) {
368 /* debug only print */
369 if(stype==NULL || stype->type==-1) printf("group verification error %s\n", ngroup->id.name);
372 outputs[a].own_index= sock->own_index;
373 outputs[a].internsock= sock;
378 outputs[a].type= -1; /* terminator code */
379 ngroup->owntype->outputs= outputs;
382 /* voila, the nodetree has the full definition for generating group-node instances! */
386 static bNodeSocket *groupnode_find_tosock(bNode *gnode, int index)
390 for(sock= gnode->inputs.first; sock; sock= sock->next)
391 if(sock->to_index==index)
396 static bNodeSocket *groupnode_find_fromsock(bNode *gnode, int index)
400 for(sock= gnode->outputs.first; sock; sock= sock->next)
401 if(sock->to_index==index)
406 bNode *nodeMakeGroupFromSelected(bNodeTree *ntree)
408 bNodeLink *link, *linkn;
409 bNode *node, *gnode, *nextn;
411 float min[2], max[2];
414 INIT_MINMAX2(min, max);
416 /* is there something to group? also do some clearing */
417 for(node= ntree->nodes.first; node; node= node->next) {
418 if(node->flag & NODE_SELECT) {
419 /* no groups in groups */
420 if(node->type==NODE_GROUP)
422 DO_MINMAX2( (&node->locx), min, max);
427 if(totnode==0) return NULL;
429 /* check if all connections are OK, no unselected node has both
430 inputs and outputs to a selection */
431 for(link= ntree->links.first; link; link= link->next) {
432 if(link->fromnode->flag & NODE_SELECT)
433 link->tonode->done |= 1;
434 if(link->tonode->flag & NODE_SELECT)
435 link->fromnode->done |= 2;
438 for(node= ntree->nodes.first; node; node= node->next) {
439 if((node->flag & NODE_SELECT)==0)
446 /* OK! new nodetree */
447 ngroup= alloc_libblock(&G.main->nodetree, ID_NT, "NodeGroup");
448 ngroup->type= ntree->type;
449 ngroup->alltypes= ntree->alltypes;
451 /* move nodes over */
452 for(node= ntree->nodes.first; node; node= nextn) {
454 if(node->flag & NODE_SELECT) {
455 BLI_remlink(&ntree->nodes, node);
456 BLI_addtail(&ngroup->nodes, node);
457 node->locx-= 0.5f*(min[0]+max[0]);
458 node->locy-= 0.5f*(min[1]+max[1]);
462 /* move links over */
463 for(link= ntree->links.first; link; link= linkn) {
465 if(link->fromnode->flag & link->tonode->flag & NODE_SELECT) {
466 BLI_remlink(&ntree->links, link);
467 BLI_addtail(&ngroup->links, link);
471 /* now we can make own group typeinfo */
472 ntreeMakeOwnType(ngroup);
474 /* make group node */
475 gnode= nodeAddNodeType(ntree, NODE_GROUP, ngroup);
476 gnode->locx= 0.5f*(min[0]+max[0]);
477 gnode->locy= 0.5f*(min[1]+max[1]);
479 /* relink external sockets */
480 for(link= ntree->links.first; link; link= link->next) {
481 if(link->tonode->flag & NODE_SELECT) {
483 link->tosock= groupnode_find_tosock(gnode, link->tosock->own_index);
484 if(link->tosock==NULL) printf("Bad!\n");
486 else if(link->fromnode->flag & NODE_SELECT) {
487 link->fromnode= gnode;
488 link->fromsock= groupnode_find_fromsock(gnode, link->fromsock->own_index);
489 if(link->fromsock==NULL) printf("Bad!\n");
496 /* note: ungroup: group_indices zero! */
498 /* here's a nasty little one, need to check users... */
499 /* should become callbackable... */
500 void nodeVerifyGroup(bNodeTree *ngroup)
503 /* group changed, so we rebuild the type definition */
504 ntreeMakeOwnType(ngroup);
506 if(ngroup->type==NTREE_SHADER) {
508 for(ma= G.main->mat.first; ma; ma= ma->id.next) {
512 /* find if group is in tree */
513 for(node= ma->nodetree->nodes.first; node; node= node->next)
514 if(node->id == (ID *)ngroup)
518 /* set all type pointers OK */
519 ntreeInitTypes(ma->nodetree);
521 for(node= ma->nodetree->nodes.first; node; node= node->next)
522 if(node->id == (ID *)ngroup)
523 nodeVerifyType(ma->nodetree, node);
528 else if(ngroup->type==NTREE_COMPOSIT) {
530 for(sce= G.main->scene.first; sce; sce= sce->id.next) {
534 /* find if group is in tree */
535 for(node= sce->nodetree->nodes.first; node; node= node->next)
536 if(node->id == (ID *)ngroup)
540 /* set all type pointers OK */
541 ntreeInitTypes(sce->nodetree);
543 for(node= sce->nodetree->nodes.first; node; node= node->next)
544 if(node->id == (ID *)ngroup)
545 nodeVerifyType(sce->nodetree, node);
552 /* also to check all users of groups. Now only used in editor for hide/unhide */
553 /* should become callbackable? */
554 void nodeGroupSocketUseFlags(bNodeTree *ngroup)
560 for(node= ngroup->nodes.first; node; node= node->next) {
561 for(sock= node->inputs.first; sock; sock= sock->next)
562 sock->flag &= ~SOCK_IN_USE;
563 for(sock= node->outputs.first; sock; sock= sock->next)
564 sock->flag &= ~SOCK_IN_USE;
567 /* tag all thats in use */
568 if(ngroup->type==NTREE_SHADER) {
570 for(ma= G.main->mat.first; ma; ma= ma->id.next) {
572 for(node= ma->nodetree->nodes.first; node; node= node->next) {
573 if(node->id==(ID *)ngroup) {
574 for(sock= node->inputs.first; sock; sock= sock->next)
577 sock->tosock->flag |= SOCK_IN_USE;
578 for(sock= node->outputs.first; sock; sock= sock->next)
579 if(nodeCountSocketLinks(ma->nodetree, sock))
581 sock->tosock->flag |= SOCK_IN_USE;
587 else if(ngroup->type==NTREE_COMPOSIT) {
589 for(sce= G.main->scene.first; sce; sce= sce->id.next) {
591 for(node= sce->nodetree->nodes.first; node; node= node->next) {
592 if(node->id==(ID *)ngroup) {
593 for(sock= node->inputs.first; sock; sock= sock->next)
596 sock->tosock->flag |= SOCK_IN_USE;
597 for(sock= node->outputs.first; sock; sock= sock->next)
598 if(nodeCountSocketLinks(sce->nodetree, sock))
600 sock->tosock->flag |= SOCK_IN_USE;
608 static void find_node_with_socket(bNodeTree *ntree, bNodeSocket *sock, bNode **nodep, int *sockindex)
614 for(node= ntree->nodes.first; node; node= node->next) {
615 for(index=0, tsock= node->inputs.first; tsock; tsock= tsock->next, index++)
620 for(index=0, tsock= node->outputs.first; tsock; tsock= tsock->next, index++)
635 /* returns 1 if its OK */
636 int nodeGroupUnGroup(bNodeTree *ntree, bNode *gnode)
638 bNodeLink *link, *linkn;
640 bNodeTree *ngroup, *wgroup;
643 ngroup= (bNodeTree *)gnode->id;
644 if(ngroup==NULL) return 0;
646 /* clear new pointers, set in copytree */
647 for(node= ntree->nodes.first; node; node= node->next)
650 wgroup= ntreeCopyTree(ngroup, 0);
652 /* add the nodes into the ntree */
653 for(node= wgroup->nodes.first; node; node= nextn) {
655 BLI_remlink(&wgroup->nodes, node);
656 BLI_addtail(&ntree->nodes, node);
657 node->locx+= gnode->locx;
658 node->locy+= gnode->locy;
659 node->flag |= NODE_SELECT;
661 /* and the internal links */
662 for(link= wgroup->links.first; link; link= linkn) {
664 BLI_remlink(&wgroup->links, link);
665 BLI_addtail(&ntree->links, link);
668 /* restore links to and from the gnode */
669 for(link= ntree->links.first; link; link= link->next) {
670 if(link->tonode==gnode) {
671 /* link->tosock->tosock is on the node we look for */
672 find_node_with_socket(ngroup, link->tosock->tosock, &nextn, &index);
673 if(nextn==NULL) printf("wrong stuff!\n");
674 else if(nextn->new==NULL) printf("wrong stuff too!\n");
676 link->tonode= nextn->new;
677 link->tosock= BLI_findlink(&link->tonode->inputs, index);
680 else if(link->fromnode==gnode) {
681 /* link->fromsock->tosock is on the node we look for */
682 find_node_with_socket(ngroup, link->fromsock->tosock, &nextn, &index);
683 if(nextn==NULL) printf("1 wrong stuff!\n");
684 else if(nextn->new==NULL) printf("1 wrong stuff too!\n");
686 link->fromnode= nextn->new;
687 link->fromsock= BLI_findlink(&link->fromnode->outputs, index);
692 /* remove the gnode & work tree */
693 ntreeFreeTree(wgroup);
696 nodeFreeNode(ntree, gnode);
701 #pragma mark /* ************** Add stuff ********** */
703 bNode *nodeAddNodeType(bNodeTree *ntree, int type, bNodeTree *ngroup)
706 bNodeType *ntype= node_get_type(ntree, type, ngroup);
707 bNodeSocketType *stype;
709 node= MEM_callocN(sizeof(bNode), "new node");
710 BLI_addtail(&ntree->nodes, node);
711 node->typeinfo= ntype;
713 BLI_strncpy(node->name, ntype->name, NODE_MAXSTR);
714 node->type= ntype->type;
715 node->flag= NODE_SELECT|ntype->flag;
716 node->width= ntype->width;
717 node->miniwidth= 15.0f; /* small value only, allows print of first chars */
720 node->id= (ID *)ngroup;
723 stype= ntype->inputs;
724 while(stype->type != -1) {
725 node_add_socket_type(&node->inputs, stype);
730 stype= ntype->outputs;
731 while(stype->type != -1) {
732 node_add_socket_type(&node->outputs, stype);
737 /* need init handler later? */
738 if(ntree->type==NTREE_SHADER) {
739 if(type==SH_NODE_MATERIAL)
740 node->custom1= SH_NODE_MAT_DIFF|SH_NODE_MAT_SPEC;
741 else if(type==SH_NODE_VALTORGB)
742 node->storage= add_colorband(1);
743 else if(type==SH_NODE_MAPPING)
744 node->storage= add_mapping();
745 else if(type==SH_NODE_CURVE_VEC)
746 node->storage= curvemapping_add(3, -1.0f, -1.0f, 1.0f, 1.0f);
747 else if(type==SH_NODE_CURVE_RGB)
748 node->storage= curvemapping_add(4, 0.0f, 0.0f, 1.0f, 1.0f);
750 else if(ntree->type==NTREE_COMPOSIT) {
751 if(type==CMP_NODE_VALTORGB)
752 node->storage= add_colorband(1);
753 else if(type==CMP_NODE_CURVE_VEC)
754 node->storage= curvemapping_add(3, -1.0f, -1.0f, 1.0f, 1.0f);
755 else if(type==CMP_NODE_CURVE_RGB)
756 node->storage= curvemapping_add(4, 0.0f, 0.0f, 1.0f, 1.0f);
762 /* keep socket listorder identical, for copying links */
763 /* ntree is the target tree */
764 bNode *nodeCopyNode(struct bNodeTree *ntree, struct bNode *node)
766 bNode *nnode= MEM_callocN(sizeof(bNode), "dupli node");
770 BLI_addtail(&ntree->nodes, nnode);
772 duplicatelist(&nnode->inputs, &node->inputs);
773 for(sock= nnode->inputs.first; sock; sock= sock->next)
776 duplicatelist(&nnode->outputs, &node->outputs);
777 for(sock= nnode->outputs.first; sock; sock= sock->next)
784 /* another candidate for handlerizing! */
785 if(ntree->type==NTREE_SHADER) {
786 if(node->type==SH_NODE_CURVE_VEC || node->type==SH_NODE_CURVE_RGB)
787 nnode->storage= curvemapping_copy(node->storage);
789 nnode->storage= MEM_dupallocN(nnode->storage);
791 else if(ntree->type==NTREE_COMPOSIT) {
792 if(node->type==CMP_NODE_CURVE_VEC || node->type==CMP_NODE_CURVE_RGB)
793 nnode->storage= curvemapping_copy(node->storage);
795 nnode->storage= MEM_dupallocN(nnode->storage);
798 nnode->storage= MEM_dupallocN(nnode->storage);
803 nnode->preview= NULL;
808 bNodeLink *nodeAddLink(bNodeTree *ntree, bNode *fromnode, bNodeSocket *fromsock, bNode *tonode, bNodeSocket *tosock)
810 bNodeLink *link= MEM_callocN(sizeof(bNodeLink), "link");
812 BLI_addtail(&ntree->links, link);
813 link->fromnode= fromnode;
814 link->fromsock= fromsock;
815 link->tonode= tonode;
816 link->tosock= tosock;
821 void nodeRemLink(bNodeTree *ntree, bNodeLink *link)
823 BLI_remlink(&ntree->links, link);
825 link->tosock->link= NULL;
830 bNodeTree *ntreeAddTree(int type)
832 bNodeTree *ntree= MEM_callocN(sizeof(bNodeTree), "new node tree");
835 ntreeInitTypes(ntree);
839 #pragma mark /* ************** Free stuff ********** */
841 /* goes over entire tree */
842 static void node_unlink_node(bNodeTree *ntree, bNode *node)
844 bNodeLink *link, *next;
848 for(link= ntree->links.first; link; link= next) {
851 if(link->fromnode==node)
853 else if(link->tonode==node)
859 for(sock= lb->first; sock; sock= sock->next) {
860 if(link->fromsock==sock || link->tosock==sock)
864 nodeRemLink(ntree, link);
870 void nodeFreeNode(bNodeTree *ntree, bNode *node)
872 node_unlink_node(ntree, node);
873 BLI_remlink(&ntree->nodes, node);
878 BLI_freelistN(&node->inputs);
879 BLI_freelistN(&node->outputs);
882 if(node->preview->rect)
883 MEM_freeN(node->preview->rect);
884 MEM_freeN(node->preview);
887 /* could be handlerized at some point, now only 1 exception still */
888 if(ntree->type==NTREE_SHADER) {
889 if(node->type==SH_NODE_CURVE_VEC || node->type==SH_NODE_CURVE_RGB)
890 curvemapping_free(node->storage);
892 MEM_freeN(node->storage);
894 else if(ntree->type==NTREE_COMPOSIT) {
895 if(node->type==CMP_NODE_CURVE_VEC || node->type==CMP_NODE_CURVE_RGB)
896 curvemapping_free(node->storage);
898 MEM_freeN(node->storage);
901 MEM_freeN(node->storage);
906 /* do not free ntree itself here, free_libblock calls this function too */
907 void ntreeFreeTree(bNodeTree *ntree)
911 if(ntree==NULL) return;
913 BLI_freelistN(&ntree->links); /* do first, then unlink_node goes fast */
915 for(node= ntree->nodes.first; node; node= next) {
917 nodeFreeNode(ntree, node);
921 if(ntree->owntype->inputs)
922 MEM_freeN(ntree->owntype->inputs);
923 if(ntree->owntype->outputs)
924 MEM_freeN(ntree->owntype->outputs);
925 MEM_freeN(ntree->owntype);
929 bNodeTree *ntreeCopyTree(bNodeTree *ntree, int internal_select)
932 bNode *node, *nnode, *last;
933 bNodeLink *link, *nlink;
937 if(ntree==NULL) return NULL;
939 if(internal_select==0) {
940 newtree= MEM_dupallocN(ntree);
941 newtree->nodes.first= newtree->nodes.last= NULL;
942 newtree->links.first= newtree->links.last= NULL;
947 last= ntree->nodes.last;
948 for(node= ntree->nodes.first; node; node= node->next) {
951 if(internal_select==0 || (node->flag & NODE_SELECT)) {
952 nnode= nodeCopyNode(newtree, node); /* sets node->new */
953 if(internal_select) {
954 node->flag &= ~NODE_SELECT;
955 nnode->flag |= NODE_SELECT;
957 node->flag &= ~NODE_ACTIVE;
959 if(node==last) break;
962 /* check for copying links */
963 for(link= ntree->links.first; link; link= link->next) {
964 if(link->fromnode->new && link->tonode->new) {
965 nlink= nodeAddLink(newtree, link->fromnode->new, NULL, link->tonode->new, NULL);
966 /* sockets were copied in order */
967 for(a=0, sock= link->fromnode->outputs.first; sock; sock= sock->next, a++) {
968 if(sock==link->fromsock)
971 nlink->fromsock= BLI_findlink(&link->fromnode->new->outputs, a);
973 for(a=0, sock= link->tonode->inputs.first; sock; sock= sock->next, a++) {
974 if(sock==link->tosock)
977 nlink->tosock= BLI_findlink(&link->tonode->new->inputs, a);
981 /* own type definition for group usage */
982 if(internal_select==0) {
984 newtree->owntype= MEM_dupallocN(ntree->owntype);
985 if(ntree->owntype->inputs)
986 newtree->owntype->inputs= MEM_dupallocN(ntree->owntype->inputs);
987 if(ntree->owntype->outputs)
988 newtree->owntype->outputs= MEM_dupallocN(ntree->owntype->outputs);
994 #pragma mark /* ************ find stuff *************** */
996 bNodeLink *nodeFindLink(bNodeTree *ntree, bNodeSocket *from, bNodeSocket *to)
1000 for(link= ntree->links.first; link; link= link->next) {
1001 if(link->fromsock==from && link->tosock==to)
1003 if(link->fromsock==to && link->tosock==from) /* hrms? */
1009 int nodeCountSocketLinks(bNodeTree *ntree, bNodeSocket *sock)
1014 for(link= ntree->links.first; link; link= link->next) {
1015 if(link->fromsock==sock || link->tosock==sock)
1021 bNode *nodeGetActive(bNodeTree *ntree)
1025 if(ntree==NULL) return NULL;
1027 for(node= ntree->nodes.first; node; node= node->next)
1028 if(node->flag & NODE_ACTIVE)
1033 /* two active flags, ID nodes have special flag for buttons display */
1034 bNode *nodeGetActiveID(bNodeTree *ntree, short idtype)
1038 if(ntree==NULL) return NULL;
1040 for(node= ntree->nodes.first; node; node= node->next)
1041 if(node->id && GS(node->id->name)==idtype)
1042 if(node->flag & NODE_ACTIVE_ID)
1047 /* two active flags, ID nodes have special flag for buttons display */
1048 void nodeClearActiveID(bNodeTree *ntree, short idtype)
1052 if(ntree==NULL) return;
1054 for(node= ntree->nodes.first; node; node= node->next)
1055 if(node->id && GS(node->id->name)==idtype)
1056 node->flag &= ~NODE_ACTIVE_ID;
1059 /* two active flags, ID nodes have special flag for buttons display */
1060 void nodeSetActive(bNodeTree *ntree, bNode *node)
1064 /* make sure only one node is active, and only one per ID type */
1065 for(tnode= ntree->nodes.first; tnode; tnode= tnode->next) {
1066 tnode->flag &= ~NODE_ACTIVE;
1068 if(node->id && tnode->id) {
1069 if(GS(node->id->name) == GS(tnode->id->name))
1070 tnode->flag &= ~NODE_ACTIVE_ID;
1074 node->flag |= NODE_ACTIVE;
1076 node->flag |= NODE_ACTIVE_ID;
1079 /* use flags are not persistant yet, groups might need different tagging, so we do it each time
1080 when we need to get this info */
1081 void ntreeSocketUseFlags(bNodeTree *ntree)
1088 for(node= ntree->nodes.first; node; node= node->next) {
1089 for(sock= node->inputs.first; sock; sock= sock->next)
1090 sock->flag &= ~SOCK_IN_USE;
1091 for(sock= node->outputs.first; sock; sock= sock->next)
1092 sock->flag &= ~SOCK_IN_USE;
1095 /* tag all thats in use */
1096 for(link= ntree->links.first; link; link= link->next) {
1097 link->fromsock->flag |= SOCK_IN_USE;
1098 link->tosock->flag |= SOCK_IN_USE;
1102 #pragma mark /* ************** dependency stuff *********** */
1104 /* node is guaranteed to be not checked before */
1105 static int node_recurs_check(bNode *node, bNode ***nsort, int level)
1109 int has_inputlinks= 0;
1114 for(sock= node->inputs.first; sock; sock= sock->next) {
1117 fromnode= sock->link->fromnode;
1118 if(fromnode->done==0) {
1119 fromnode->level= node_recurs_check(fromnode, nsort, level);
1123 // printf("node sort %s level %d\n", node->name, level);
1133 void ntreeSolveOrder(bNodeTree *ntree)
1135 bNode *node, **nodesort, **nsort;
1140 /* the solve-order is called on each tree change, so we should be sure no exec can be running */
1141 ntreeEndExecTree(ntree);
1143 /* set links pointers the input sockets, to find dependencies */
1144 /* first clear data */
1145 for(node= ntree->nodes.first; node; node= node->next) {
1148 for(sock= node->inputs.first; sock; sock= sock->next)
1154 for(link= ntree->links.first; link; link= link->next) {
1155 link->tosock->link= link;
1158 nsort= nodesort= MEM_callocN(totnode*sizeof(void *), "sorted node array");
1160 /* recursive check */
1161 for(node= ntree->nodes.first; node; node= node->next) {
1163 node->level= node_recurs_check(node, &nsort, 0);
1167 /* re-insert nodes in order, first a paranoia check */
1168 for(a=0; a<totnode; a++) {
1169 if(nodesort[a]==NULL)
1173 printf("sort error in node tree");
1175 ntree->nodes.first= ntree->nodes.last= NULL;
1176 for(a=0; a<totnode; a++)
1177 BLI_addtail(&ntree->nodes, nodesort[a]);
1180 MEM_freeN(nodesort);
1182 /* find the active outputs, might become tree type dependant handler */
1183 for(node= ntree->nodes.first; node; node= node->next) {
1184 if(node->typeinfo->nclass==NODE_CLASS_OUTPUT) {
1187 /* there is more types having output class, each one is checked */
1188 for(tnode= ntree->nodes.first; tnode; tnode= tnode->next) {
1189 if(tnode->typeinfo->nclass==NODE_CLASS_OUTPUT) {
1190 if(tnode->type==node->type) {
1192 tnode->flag |= NODE_DO_OUTPUT;
1194 tnode->flag &= ~NODE_DO_OUTPUT;
1202 /* here we could recursively set which nodes have to be done,
1203 might be different for editor or for "real" use... */
1206 #pragma mark /* *************** preview *********** */
1208 /* if node->preview, then we assume the rect to exist */
1210 static void nodeInitPreview(bNode *node, int xsize, int ysize)
1213 /* sanity checks & initialize */
1214 if(node->preview && node->preview->rect) {
1215 if(node->preview->xsize!=xsize && node->preview->ysize!=ysize) {
1216 MEM_freeN(node->preview->rect);
1217 node->preview->rect= NULL;
1221 if(node->preview==NULL) {
1222 node->preview= MEM_callocN(sizeof(bNodePreview), "node preview");
1223 printf("added preview %s\n", node->name);
1226 /* node previews can get added with variable size this way */
1227 if(xsize==0 || ysize==0)
1230 if(node->preview->rect==NULL) {
1231 node->preview->rect= MEM_callocN(4*xsize + xsize*ysize*sizeof(float)*4, "node preview rect");
1232 node->preview->xsize= xsize;
1233 node->preview->ysize= ysize;
1237 void ntreeInitPreview(bNodeTree *ntree, int xsize, int ysize)
1244 for(node= ntree->nodes.first; node; node= node->next) {
1245 if(node->typeinfo->flag & NODE_PREVIEW) /* hrms, check for closed nodes? */
1246 nodeInitPreview(node, xsize, ysize);
1247 if(node->type==NODE_GROUP && (node->flag & NODE_GROUP_EDIT))
1248 ntreeInitPreview((bNodeTree *)node->id, xsize, ysize);
1252 void nodeAddToPreview(bNode *node, float *col, int x, int y)
1254 bNodePreview *preview= node->preview;
1257 if(x<preview->xsize && y<preview->ysize) {
1258 float *tar= preview->rect+ 4*((preview->xsize*y) + x);
1261 else printf("prv out bound x y %d %d\n", x, y);
1263 else printf("prv out bound x y %d %d\n", x, y);
1269 #pragma mark /* ******************* executing ************* */
1271 /* see notes at ntreeBeginExecTree */
1272 static void group_node_get_stack(bNode *node, bNodeStack *stack, bNodeStack **in, bNodeStack **out, bNodeStack **gin, bNodeStack **gout)
1276 /* build pointer stack */
1277 for(sock= node->inputs.first; sock; sock= sock->next) {
1279 /* yep, intern can have link or is hidden socket */
1281 *(in++)= stack + sock->link->fromsock->stack_index;
1286 *(in++)= gin[sock->stack_index_ext];
1289 for(sock= node->outputs.first; sock; sock= sock->next) {
1291 *(out++)= stack + sock->stack_index;
1293 *(out++)= gout[sock->stack_index_ext];
1297 static void node_group_execute(bNodeStack *stack, void *data, bNode *gnode, bNodeStack **in, bNodeStack **out)
1300 bNodeTree *ntree= (bNodeTree *)gnode->id;
1301 bNodeStack *nsin[MAX_SOCKET]; /* arbitrary... watch this */
1302 bNodeStack *nsout[MAX_SOCKET]; /* arbitrary... watch this */
1304 if(ntree==NULL) return;
1306 stack+= gnode->stack_index;
1308 for(node= ntree->nodes.first; node; node= node->next) {
1309 if(node->typeinfo->execfunc) {
1310 group_node_get_stack(node, stack, nsin, nsout, in, out);
1311 node->typeinfo->execfunc(data, node, nsin, nsout);
1316 /* recursively called for groups */
1317 /* we set all trees on own local indices, but put a total counter
1318 in the groups, so each instance of a group has own stack */
1319 static int ntree_begin_exec_tree(bNodeTree *ntree)
1323 int index= 0, index_in= 0, index_out= 0;
1325 if((ntree->init & NTREE_TYPE_INIT)==0)
1326 ntreeInitTypes(ntree);
1328 /* create indices for stack, check preview */
1329 for(node= ntree->nodes.first; node; node= node->next) {
1331 for(sock= node->inputs.first; sock; sock= sock->next) {
1333 sock->stack_index_ext= index_in++;
1336 for(sock= node->outputs.first; sock; sock= sock->next) {
1337 sock->stack_index= index++;
1339 sock->stack_index_ext= index_out++;
1342 if(node->type==NODE_GROUP) {
1345 node->stack_index= index;
1346 index+= ntree_begin_exec_tree((bNodeTree *)node->id);
1348 /* copy internal data from internal nodes to own input sockets */
1349 for(sock= node->inputs.first; sock; sock= sock->next) {
1351 sock->ns= sock->tosock->ns;
1361 /* stack indices make sure all nodes only write in allocated data, for making it thread safe */
1362 /* only root tree gets the stack, to enable instances to have own stack entries */
1363 /* only two threads now! */
1364 /* per tree (and per group) unique indices are created */
1365 /* the index_ext we need to be able to map from groups to the group-node own stack */
1367 void ntreeBeginExecTree(bNodeTree *ntree)
1370 /* goes recursive over all groups */
1371 ntree->stacksize= ntree_begin_exec_tree(ntree);
1373 if(ntree->stacksize) {
1378 /* allocate stack */
1379 ns=ntree->stack= MEM_callocN(ntree->stacksize*sizeof(bNodeStack), "node stack");
1381 /* tag inputs, the get_stack() gives own socket stackdata if not in use */
1382 for(a=0; a<ntree->stacksize; a++, ns++) ns->hasinput= 1;
1384 /* tag outputs, so we know when we can skip operations */
1385 for(node= ntree->nodes.first; node; node= node->next) {
1387 for(sock= node->inputs.first; sock; sock= sock->next) {
1389 ns= ntree->stack + sock->link->fromsock->stack_index;
1395 ntree->stack1= MEM_dupallocN(ntree->stack);
1398 ntree->init |= NTREE_EXEC_INIT;
1401 void ntreeEndExecTree(bNodeTree *ntree)
1404 if(ntree->init & NTREE_EXEC_INIT) {
1408 /* another callback candidate! */
1409 if(ntree->type==NTREE_COMPOSIT) {
1413 for(ns= ntree->stack, a=0; a<ntree->stacksize; a++, ns++)
1415 free_compbuf(ns->data);
1416 for(ns= ntree->stack1, a=0; a<ntree->stacksize; a++, ns++)
1418 free_compbuf(ns->data);
1420 MEM_freeN(ntree->stack);
1422 MEM_freeN(ntree->stack1);
1423 ntree->stack1= NULL;
1426 ntree->init &= ~NTREE_EXEC_INIT;
1430 static void node_get_stack(bNode *node, bNodeStack *stack, bNodeStack **in, bNodeStack **out)
1434 /* build pointer stack */
1435 for(sock= node->inputs.first; sock; sock= sock->next) {
1437 *(in++)= stack + sock->link->fromsock->stack_index;
1442 for(sock= node->outputs.first; sock; sock= sock->next) {
1443 *(out++)= stack + sock->stack_index;
1447 /* nodes are presorted, so exec is in order of list */
1448 void ntreeExecTree(bNodeTree *ntree, void *callerdata, int thread)
1451 bNodeStack *nsin[MAX_SOCKET]; /* arbitrary... watch this */
1452 bNodeStack *nsout[MAX_SOCKET]; /* arbitrary... watch this */
1455 /* only when initialized */
1456 if((ntree->init & NTREE_EXEC_INIT)==0)
1457 ntreeBeginExecTree(ntree);
1460 stack= ntree->stack1;
1462 stack= ntree->stack;
1464 for(node= ntree->nodes.first; node; node= node->next) {
1465 if(node->typeinfo->execfunc) {
1466 node_get_stack(node, stack, nsin, nsout);
1467 node->typeinfo->execfunc(callerdata, node, nsin, nsout);
1469 else if(node->type==NODE_GROUP && node->id) {
1470 node_get_stack(node, stack, nsin, nsout);
1471 node_group_execute(stack, callerdata, node, nsin, nsout);