Implements a new operator for detaching nodes. In the process i overhauled the node...
[blender-staging.git] / source / blender / nodes / intern / node_exec.c
1 /*
2  * ***** BEGIN GPL LICENSE BLOCK *****
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License
6  * as published by the Free Software Foundation; either version 2
7  * of the License, or (at your option) any later version. 
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software Foundation,
16  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17  *
18  * The Original Code is Copyright (C) 2007 Blender Foundation.
19  * All rights reserved.
20  *
21  * The Original Code is: all of this file.
22  *
23  * Contributor(s): Nathan Letwory.
24  *
25  * ***** END GPL LICENSE BLOCK *****
26  */
27
28 /** \file blender/nodes/intern/node_exec.c
29  *  \ingroup nodes
30  */
31
32
33 #include "DNA_node_types.h"
34
35 #include "BLI_listbase.h"
36 #include "BLI_math.h"
37 #include "BLI_utildefines.h"
38
39 #include "BKE_node.h"
40
41 #include "MEM_guardedalloc.h"
42
43 #include "node_exec.h"
44
45
46 /* for a given socket, find the actual stack entry */
47 bNodeStack *node_get_socket_stack(bNodeStack *stack, bNodeSocket *sock)
48 {
49         return stack + sock->stack_index;
50 }
51
52 void node_get_stack(bNode *node, bNodeStack *stack, bNodeStack **in, bNodeStack **out)
53 {
54         bNodeSocket *sock;
55         
56         /* build pointer stack */
57         if (in) {
58                 for(sock= node->inputs.first; sock; sock= sock->next) {
59                         *(in++) = node_get_socket_stack(stack, sock);
60                 }
61         }
62         
63         if (out) {
64                 for(sock= node->outputs.first; sock; sock= sock->next) {
65                         *(out++) = node_get_socket_stack(stack, sock);
66                 }
67         }
68 }
69
70 void node_init_input_index(bNodeSocket *sock, int *index)
71 {
72         if (sock->link && sock->link->fromsock) {
73                 sock->stack_index = sock->link->fromsock->stack_index;
74         }
75         else {
76                 sock->stack_index = (*index)++;
77         }
78 }
79
80 void node_init_output_index(bNodeSocket *sock, int *index)
81 {
82         sock->stack_index = (*index)++;
83 }
84
85 /* basic preparation of socket stacks */
86 static struct bNodeStack *setup_stack(bNodeStack *stack, bNodeSocket *sock)
87 {
88         bNodeStack *ns = node_get_socket_stack(stack, sock);
89         float null_value[4]= {0.0f, 0.0f, 0.0f, 0.0f};
90         
91         /* don't mess with remote socket stacks, these are initialized by other nodes! */
92         if (sock->link)
93                 return ns;
94         
95         ns->sockettype = sock->type;
96         
97         if (sock->default_value) {
98                 switch (sock->type) {
99                 case SOCK_FLOAT:
100                         ns->vec[0] = ((bNodeSocketValueFloat*)sock->default_value)->value;
101                         break;
102                 case SOCK_VECTOR:
103                         copy_v3_v3(ns->vec, ((bNodeSocketValueVector*)sock->default_value)->value);
104                         break;
105                 case SOCK_RGBA:
106                         copy_v4_v4(ns->vec, ((bNodeSocketValueRGBA*)sock->default_value)->value);
107                         break;
108                 }
109         }
110         else {
111                 switch (sock->type) {
112                 case SOCK_FLOAT:
113                         ns->vec[0] = 0.0f;
114                         break;
115                 case SOCK_VECTOR:
116                         copy_v3_v3(ns->vec, null_value);
117                         break;
118                 case SOCK_RGBA:
119                         copy_v4_v4(ns->vec, null_value);
120                         break;
121                 }
122         }
123         
124         return ns;
125 }
126
127 bNodeTreeExec *ntree_exec_begin(bNodeTree *ntree)
128 {
129         bNodeTreeExec *exec;
130         bNode *node;
131         bNodeExec *nodeexec;
132         bNodeSocket *sock, *gsock;
133         bNodeStack *ns;
134         int index= 0;
135         bNode **nodelist;
136         int totnodes, n;
137         
138         if((ntree->init & NTREE_TYPE_INIT)==0)
139                 ntreeInitTypes(ntree);
140         
141         /* get a dependency-sorted list of nodes */
142         ntreeGetDependencyList(ntree, &nodelist, &totnodes);
143         
144         /* XXX could let callbacks do this for specialized data */
145         exec = MEM_callocN(sizeof(bNodeTreeExec), "node tree execution data");
146         /* backpointer to node tree */
147         exec->nodetree = ntree;
148         
149         /* group inputs essentially work as outputs */
150         for(gsock=ntree->inputs.first; gsock; gsock = gsock->next)
151                 node_init_output_index(gsock, &index);
152         /* set stack indexes */
153         for(n=0; n < totnodes; ++n) {
154                 node = nodelist[n];
155                 
156                 node->stack_index = index;
157                 
158                 /* init node socket stack indexes */
159                 for (sock=node->inputs.first; sock; sock=sock->next)
160                         node_init_input_index(sock, &index);
161                 for (sock=node->outputs.first; sock; sock=sock->next)
162                         node_init_output_index(sock, &index);
163         }
164         /* group outputs essentially work as inputs */
165         for(gsock=ntree->outputs.first; gsock; gsock = gsock->next)
166                 node_init_input_index(gsock, &index);
167         
168         /* allocated exec data pointers for nodes */
169         exec->totnodes = totnodes;
170         exec->nodeexec = MEM_callocN(exec->totnodes * sizeof(bNodeExec), "node execution data");
171         /* allocate data pointer for node stack */
172         exec->stacksize = index;
173         exec->stack = MEM_callocN(exec->stacksize * sizeof(bNodeStack), "bNodeStack");
174         
175         /* all non-const results are considered inputs */
176         for (n=0; n < exec->stacksize; ++n)
177                 exec->stack[n].hasinput = 1;
178         
179         /* prepare group tree inputs */
180         for (sock=ntree->inputs.first; sock; sock=sock->next) {
181                 /* ns = */ setup_stack(exec->stack, sock);
182         }
183         /* prepare all internal nodes for execution */
184         for(n=0, nodeexec= exec->nodeexec; n < totnodes; ++n, ++nodeexec) {
185                 node = nodeexec->node = nodelist[n];
186                 
187                 /* tag inputs */
188                 for (sock=node->inputs.first; sock; sock=sock->next) {
189                         /* disable the node if an input link is invalid */
190                         if(sock->link && !(sock->link->flag & NODE_LINK_VALID))
191                                 node->need_exec= 0;
192                         
193                         ns = setup_stack(exec->stack, sock);
194                         ns->hasoutput = 1;
195                 }
196                 
197                 /* tag all outputs */
198                 for (sock=node->outputs.first; sock; sock=sock->next) {
199                         /* ns = */ setup_stack(exec->stack, sock);
200                 }
201                 
202                 if(node->typeinfo->initexecfunc)
203                         nodeexec->data = node->typeinfo->initexecfunc(node);
204         }
205         /* prepare group tree outputs */
206         for (sock=ntree->outputs.first; sock; sock=sock->next) {
207                 ns = setup_stack(exec->stack, sock);
208                 ns->hasoutput = 1;
209         }
210         
211         if (nodelist)
212                 MEM_freeN(nodelist);
213         
214         return exec;
215 }
216
217 void ntree_exec_end(bNodeTreeExec *exec)
218 {
219         bNodeExec *nodeexec;
220         int n;
221         
222         if (exec->stack)
223                 MEM_freeN(exec->stack);
224         
225         for(n=0, nodeexec= exec->nodeexec; n < exec->totnodes; ++n, ++nodeexec) {
226                 if (nodeexec->node->typeinfo->freeexecfunc)
227                         nodeexec->node->typeinfo->freeexecfunc(nodeexec->node, nodeexec->data);
228         }
229         
230         if (exec->nodeexec)
231                 MEM_freeN(exec->nodeexec);
232         
233         MEM_freeN(exec);
234 }
235
236 /**** Compositor/Material/Texture trees ****/
237
238 bNodeThreadStack *ntreeGetThreadStack(bNodeTreeExec *exec, int thread)
239 {
240         ListBase *lb= &exec->threadstack[thread];
241         bNodeThreadStack *nts;
242         
243         for(nts=lb->first; nts; nts=nts->next) {
244                 if(!nts->used) {
245                         nts->used= 1;
246                         break;
247                 }
248         }
249         
250         if (!nts) {
251                 nts= MEM_callocN(sizeof(bNodeThreadStack), "bNodeThreadStack");
252                 nts->stack= MEM_dupallocN(exec->stack);
253                 nts->used= 1;
254                 BLI_addtail(lb, nts);
255         }
256
257         return nts;
258 }
259
260 void ntreeReleaseThreadStack(bNodeThreadStack *nts)
261 {
262         nts->used = 0;
263 }
264
265 void ntreeExecNodes(bNodeTreeExec *exec, void *callerdata, int thread)
266 {
267         bNodeStack *nsin[MAX_SOCKET];   /* arbitrary... watch this */
268         bNodeStack *nsout[MAX_SOCKET];  /* arbitrary... watch this */
269         bNodeExec *nodeexec;
270         bNode *node;
271         int n;
272         
273         /* nodes are presorted, so exec is in order of list */
274         
275         for(n=0, nodeexec= exec->nodeexec; n < exec->totnodes; ++n, ++nodeexec) {
276                 node = nodeexec->node;
277                 if(node->need_exec) {
278                         node_get_stack(node, exec->stack, nsin, nsout);
279                         /* Handle muted nodes...
280                          * If the mute func is not set, assume the node should never be muted,
281                          * and hence execute it!
282                          */
283                         if(node->typeinfo->execfunc)
284                                 node->typeinfo->execfunc(callerdata, node, nsin, nsout);
285                         else if (node->typeinfo->newexecfunc)
286                                 node->typeinfo->newexecfunc(callerdata, thread, node, nodeexec->data, nsin, nsout);
287                 }
288         }
289 }
290
291 void ntreeExecThreadNodes(bNodeTreeExec *exec, bNodeThreadStack *nts, void *callerdata, int thread)
292 {
293         bNodeStack *nsin[MAX_SOCKET];   /* arbitrary... watch this */
294         bNodeStack *nsout[MAX_SOCKET];  /* arbitrary... watch this */
295         bNodeExec *nodeexec;
296         bNode *node;
297         int n;
298         
299         /* nodes are presorted, so exec is in order of list */
300         
301         for(n=0, nodeexec= exec->nodeexec; n < exec->totnodes; ++n, ++nodeexec) {
302                 node = nodeexec->node;
303                 if(node->need_exec) {
304                         node_get_stack(node, nts->stack, nsin, nsout);
305                         /* Handle muted nodes...
306                          * If the mute func is not set, assume the node should never be muted,
307                          * and hence execute it!
308                          */
309                         if(node->typeinfo->execfunc)
310                                 node->typeinfo->execfunc(callerdata, node, nsin, nsout);
311                         else if (node->typeinfo->newexecfunc)
312                                 node->typeinfo->newexecfunc(callerdata, thread, node, nodeexec->data, nsin, nsout);
313                 }
314         }
315 }