GSOC 2013 paint
[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_utildefines.h"
37
38 #include "BKE_global.h"
39 #include "BKE_node.h"
40
41 #include "MEM_guardedalloc.h"
42
43 #include "node_exec.h"
44 #include "node_util.h"
45
46
47 /* supported socket types in old nodes */
48 int node_exec_socket_use_stack(bNodeSocket *sock)
49 {
50         return ELEM(sock->type, SOCK_FLOAT, SOCK_VECTOR, SOCK_RGBA, SOCK_SHADER);
51 }
52
53 /* for a given socket, find the actual stack entry */
54 bNodeStack *node_get_socket_stack(bNodeStack *stack, bNodeSocket *sock)
55 {
56         if (stack && sock && sock->stack_index >= 0)
57                 return stack + sock->stack_index;
58         return NULL;
59 }
60
61 void node_get_stack(bNode *node, bNodeStack *stack, bNodeStack **in, bNodeStack **out)
62 {
63         bNodeSocket *sock;
64         
65         /* build pointer stack */
66         if (in) {
67                 for (sock = node->inputs.first; sock; sock = sock->next) {
68                         *(in++) = node_get_socket_stack(stack, sock);
69                 }
70         }
71         
72         if (out) {
73                 for (sock = node->outputs.first; sock; sock = sock->next) {
74                         *(out++) = node_get_socket_stack(stack, sock);
75                 }
76         }
77 }
78
79 static void node_init_input_index(bNodeSocket *sock, int *index)
80 {
81         if (sock->link && sock->link->fromsock) {
82                 sock->stack_index = sock->link->fromsock->stack_index;
83         }
84         else {
85                 if (node_exec_socket_use_stack(sock))
86                         sock->stack_index = (*index)++;
87                 else
88                         sock->stack_index = -1;
89         }
90 }
91
92 static void node_init_output_index(bNodeSocket *sock, int *index, ListBase *internal_links)
93 {
94         if (internal_links) {
95                 bNodeLink *link;
96                 /* copy the stack index from internally connected input to skip the node */
97                 for (link = internal_links->first; link; link = link->next) {
98                         if (link->tosock == sock) {
99                                 sock->stack_index = link->fromsock->stack_index;
100                                 /* set the link pointer to indicate that this socket
101                                  * should not overwrite the stack value!
102                                  */
103                                 sock->link = link;
104                                 break;
105                         }
106                 }
107                 /* if not internally connected, assign a new stack index anyway to avoid bad stack access */
108                 if (!link) {
109                         if (node_exec_socket_use_stack(sock))
110                                 sock->stack_index = (*index)++;
111                         else
112                                 sock->stack_index = -1;
113                 }
114         }
115         else {
116                 if (node_exec_socket_use_stack(sock))
117                         sock->stack_index = (*index)++;
118                 else
119                         sock->stack_index = -1;
120         }
121 }
122
123 /* basic preparation of socket stacks */
124 static struct bNodeStack *setup_stack(bNodeStack *stack, bNodeTree *ntree, bNode *node, bNodeSocket *sock)
125 {
126         bNodeStack *ns = node_get_socket_stack(stack, sock);
127         if (!ns)
128                 return NULL;
129         
130         /* don't mess with remote socket stacks, these are initialized by other nodes! */
131         if (sock->link)
132                 return ns;
133         
134         ns->sockettype = sock->type;
135         
136         switch (sock->type) {
137                 case SOCK_FLOAT:
138                         ns->vec[0] = node_socket_get_float(ntree, node, sock);
139                         break;
140                 case SOCK_VECTOR:
141                         node_socket_get_vector(ntree, node, sock, ns->vec);
142                         break;
143                 case SOCK_RGBA:
144                         node_socket_get_color(ntree, node, sock, ns->vec);
145                         break;
146         }
147         
148         return ns;
149 }
150
151 bNodeTreeExec *ntree_exec_begin(bNodeExecContext *context, bNodeTree *ntree, bNodeInstanceKey parent_key)
152 {
153         bNodeTreeExec *exec;
154         bNode *node;
155         bNodeExec *nodeexec;
156         bNodeInstanceKey nodekey;
157         bNodeSocket *sock;
158         bNodeStack *ns;
159         int index;
160         bNode **nodelist;
161         int totnodes, n;
162         
163         /* ensure all sock->link pointers and node levels are correct */
164         ntreeUpdateTree(G.main, ntree);
165         
166         /* get a dependency-sorted list of nodes */
167         ntreeGetDependencyList(ntree, &nodelist, &totnodes);
168         
169         /* XXX could let callbacks do this for specialized data */
170         exec = MEM_callocN(sizeof(bNodeTreeExec), "node tree execution data");
171         /* backpointer to node tree */
172         exec->nodetree = ntree;
173         
174         /* set stack indices */
175         index = 0;
176         for (n = 0; n < totnodes; ++n) {
177                 node = nodelist[n];
178                 
179                 node->stack_index = index;
180                 
181                 /* init node socket stack indexes */
182                 for (sock = node->inputs.first; sock; sock = sock->next)
183                         node_init_input_index(sock, &index);
184                 
185                 if (node->flag & NODE_MUTED || node->type == NODE_REROUTE) {
186                         for (sock = node->outputs.first; sock; sock = sock->next)
187                                 node_init_output_index(sock, &index, &node->internal_links);
188                 }
189                 else {
190                         for (sock = node->outputs.first; sock; sock = sock->next)
191                                 node_init_output_index(sock, &index, NULL);
192                 }
193         }
194         
195         /* allocated exec data pointers for nodes */
196         exec->totnodes = totnodes;
197         exec->nodeexec = MEM_callocN(exec->totnodes * sizeof(bNodeExec), "node execution data");
198         /* allocate data pointer for node stack */
199         exec->stacksize = index;
200         exec->stack = MEM_callocN(exec->stacksize * sizeof(bNodeStack), "bNodeStack");
201         
202         /* all non-const results are considered inputs */
203         for (n = 0; n < exec->stacksize; ++n)
204                 exec->stack[n].hasinput = 1;
205         
206         /* prepare all nodes for execution */
207         for (n = 0, nodeexec = exec->nodeexec; n < totnodes; ++n, ++nodeexec) {
208                 node = nodeexec->node = nodelist[n];
209                 nodeexec->freeexecfunc = node->typeinfo->freeexecfunc;
210                 
211                 /* tag inputs */
212                 for (sock = node->inputs.first; sock; sock = sock->next) {
213                         /* disable the node if an input link is invalid */
214                         if (sock->link && !(sock->link->flag & NODE_LINK_VALID))
215                                 node->need_exec = 0;
216                         
217                         ns = setup_stack(exec->stack, ntree, node, sock);
218                         if (ns)
219                                 ns->hasoutput = 1;
220                 }
221                 
222                 /* tag all outputs */
223                 for (sock = node->outputs.first; sock; sock = sock->next) {
224                         /* ns = */ setup_stack(exec->stack, ntree, node, sock);
225                 }
226                 
227                 nodekey = BKE_node_instance_key(parent_key, ntree, node);
228                 nodeexec->data.preview = context->previews ? BKE_node_instance_hash_lookup(context->previews, nodekey) : NULL;
229                 if (node->typeinfo->initexecfunc)
230                         nodeexec->data.data = node->typeinfo->initexecfunc(context, node, nodekey);
231         }
232         
233         if (nodelist)
234                 MEM_freeN(nodelist);
235         
236         return exec;
237 }
238
239 void ntree_exec_end(bNodeTreeExec *exec)
240 {
241         bNodeExec *nodeexec;
242         int n;
243         
244         if (exec->stack)
245                 MEM_freeN(exec->stack);
246         
247         for (n = 0, nodeexec = exec->nodeexec; n < exec->totnodes; ++n, ++nodeexec) {
248                 if (nodeexec->freeexecfunc)
249                         nodeexec->freeexecfunc(nodeexec->data.data);
250         }
251         
252         if (exec->nodeexec)
253                 MEM_freeN(exec->nodeexec);
254         
255         MEM_freeN(exec);
256 }
257
258 /**** Material/Texture trees ****/
259
260 bNodeThreadStack *ntreeGetThreadStack(bNodeTreeExec *exec, int thread)
261 {
262         ListBase *lb = &exec->threadstack[thread];
263         bNodeThreadStack *nts;
264         
265         for (nts = lb->first; nts; nts = nts->next) {
266                 if (!nts->used) {
267                         nts->used = true;
268                         break;
269                 }
270         }
271         
272         if (!nts) {
273                 nts = MEM_callocN(sizeof(bNodeThreadStack), "bNodeThreadStack");
274                 nts->stack = MEM_dupallocN(exec->stack);
275                 nts->used = true;
276                 BLI_addtail(lb, nts);
277         }
278
279         return nts;
280 }
281
282 void ntreeReleaseThreadStack(bNodeThreadStack *nts)
283 {
284         nts->used = 0;
285 }
286
287 bool ntreeExecThreadNodes(bNodeTreeExec *exec, bNodeThreadStack *nts, void *callerdata, int thread)
288 {
289         bNodeStack *nsin[MAX_SOCKET] = {NULL};   /* arbitrary... watch this */
290         bNodeStack *nsout[MAX_SOCKET] = {NULL};  /* arbitrary... watch this */
291         bNodeExec *nodeexec;
292         bNode *node;
293         int n;
294         
295         /* nodes are presorted, so exec is in order of list */
296         
297         for (n = 0, nodeexec = exec->nodeexec; n < exec->totnodes; ++n, ++nodeexec) {
298                 node = nodeexec->node;
299                 if (node->need_exec) {
300                         node_get_stack(node, nts->stack, nsin, nsout);
301                         /* Handle muted nodes...
302                          * If the mute func is not set, assume the node should never be muted,
303                          * and hence execute it!
304                          */
305 //                      if (node->typeinfo->compatibility == NODE_NEW_SHADING)
306 //                              return false;
307                         if (node->typeinfo->execfunc)
308                                 node->typeinfo->execfunc(callerdata, thread, node, &nodeexec->data, nsin, nsout);
309                 }
310         }
311         
312         /* signal to that all went OK, for render */
313         return true;
314 }