| 
									
										
										
										
											2011-10-23 17:52:20 +00:00
										 |  |  | /*
 | 
					
						
							| 
									
										
										
										
											2011-09-05 21:01:50 +00:00
										 |  |  |  * This program is free software; you can redistribute it and/or | 
					
						
							|  |  |  |  * modify it under the terms of the GNU General Public License | 
					
						
							|  |  |  |  * as published by the Free Software Foundation; either version 2 | 
					
						
							| 
									
										
										
										
											2018-06-01 18:19:39 +02:00
										 |  |  |  * of the License, or (at your option) any later version. | 
					
						
							| 
									
										
										
										
											2011-09-05 21:01:50 +00:00
										 |  |  |  * | 
					
						
							|  |  |  |  * This program is distributed in the hope that it will be useful, | 
					
						
							|  |  |  |  * but WITHOUT ANY WARRANTY; without even the implied warranty of | 
					
						
							|  |  |  |  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | 
					
						
							|  |  |  |  * GNU General Public License for more details. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * You should have received a copy of the GNU General Public License | 
					
						
							|  |  |  |  * along with this program; if not, write to the Free Software Foundation, | 
					
						
							|  |  |  |  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * The Original Code is Copyright (C) 2007 Blender Foundation. | 
					
						
							|  |  |  |  * All rights reserved. | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /** \file blender/nodes/intern/node_exec.c
 | 
					
						
							|  |  |  |  *  \ingroup nodes | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include "DNA_node_types.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include "BLI_listbase.h"
 | 
					
						
							|  |  |  | #include "BLI_utildefines.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-05-07 15:28:42 +00:00
										 |  |  | #include "BKE_global.h"
 | 
					
						
							| 
									
										
										
										
											2011-09-05 21:01:50 +00:00
										 |  |  | #include "BKE_node.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include "MEM_guardedalloc.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include "node_exec.h"
 | 
					
						
							| 
									
										
										
										
											2013-03-18 16:34:57 +00:00
										 |  |  | #include "node_util.h"
 | 
					
						
							| 
									
										
										
										
											2011-09-05 21:01:50 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-03-18 16:34:57 +00:00
										 |  |  | /* supported socket types in old nodes */ | 
					
						
							|  |  |  | int node_exec_socket_use_stack(bNodeSocket *sock) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2014-07-20 01:30:29 +10:00
										 |  |  | 	return ELEM(sock->type, SOCK_FLOAT, SOCK_VECTOR, SOCK_RGBA, SOCK_SHADER); | 
					
						
							| 
									
										
										
										
											2013-03-18 16:34:57 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-09-05 21:01:50 +00:00
										 |  |  | /* for a given socket, find the actual stack entry */ | 
					
						
							|  |  |  | bNodeStack *node_get_socket_stack(bNodeStack *stack, bNodeSocket *sock) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2013-03-18 16:34:57 +00:00
										 |  |  | 	if (stack && sock && sock->stack_index >= 0) | 
					
						
							| 
									
										
										
										
											2012-06-01 13:42:18 +00:00
										 |  |  | 		return stack + sock->stack_index; | 
					
						
							|  |  |  | 	return NULL; | 
					
						
							| 
									
										
										
										
											2011-09-05 21:01:50 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void node_get_stack(bNode *node, bNodeStack *stack, bNodeStack **in, bNodeStack **out) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	bNodeSocket *sock; | 
					
						
							| 
									
										
										
										
											2018-06-08 08:07:48 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-09-05 21:01:50 +00:00
										 |  |  | 	/* build pointer stack */ | 
					
						
							|  |  |  | 	if (in) { | 
					
						
							| 
									
										
										
										
											2013-05-27 08:04:07 +00:00
										 |  |  | 		for (sock = node->inputs.first; sock; sock = sock->next) { | 
					
						
							| 
									
										
										
										
											2011-09-05 21:01:50 +00:00
										 |  |  | 			*(in++) = node_get_socket_stack(stack, sock); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2018-06-08 08:07:48 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-09-05 21:01:50 +00:00
										 |  |  | 	if (out) { | 
					
						
							| 
									
										
										
										
											2013-05-27 08:04:07 +00:00
										 |  |  | 		for (sock = node->outputs.first; sock; sock = sock->next) { | 
					
						
							| 
									
										
										
										
											2011-09-05 21:01:50 +00:00
										 |  |  | 			*(out++) = node_get_socket_stack(stack, sock); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-10-24 12:57:48 +00:00
										 |  |  | static void node_init_input_index(bNodeSocket *sock, int *index) | 
					
						
							| 
									
										
										
										
											2011-09-05 21:01:50 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2017-06-01 12:18:57 +02:00
										 |  |  | 	/* Only consider existing link if from socket is valid! */ | 
					
						
							|  |  |  | 	if (sock->link && sock->link->fromsock && sock->link->fromsock->stack_index >= 0) { | 
					
						
							| 
									
										
										
										
											2011-09-05 21:01:50 +00:00
										 |  |  | 		sock->stack_index = sock->link->fromsock->stack_index; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	else { | 
					
						
							| 
									
										
										
										
											2013-03-18 16:34:57 +00:00
										 |  |  | 		if (node_exec_socket_use_stack(sock)) | 
					
						
							|  |  |  | 			sock->stack_index = (*index)++; | 
					
						
							|  |  |  | 		else | 
					
						
							|  |  |  | 			sock->stack_index = -1; | 
					
						
							| 
									
										
										
										
											2011-09-05 21:01:50 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-10-24 12:57:48 +00:00
										 |  |  | static void node_init_output_index(bNodeSocket *sock, int *index, ListBase *internal_links) | 
					
						
							| 
									
										
										
										
											2011-09-05 21:01:50 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2012-10-24 12:57:48 +00:00
										 |  |  | 	if (internal_links) { | 
					
						
							|  |  |  | 		bNodeLink *link; | 
					
						
							|  |  |  | 		/* copy the stack index from internally connected input to skip the node */ | 
					
						
							|  |  |  | 		for (link = internal_links->first; link; link = link->next) { | 
					
						
							|  |  |  | 			if (link->tosock == sock) { | 
					
						
							|  |  |  | 				sock->stack_index = link->fromsock->stack_index; | 
					
						
							| 
									
										
										
										
											2013-07-31 12:26:03 +00:00
										 |  |  | 				/* set the link pointer to indicate that this socket
 | 
					
						
							|  |  |  | 				 * should not overwrite the stack value! | 
					
						
							|  |  |  | 				 */ | 
					
						
							|  |  |  | 				sock->link = link; | 
					
						
							| 
									
										
										
										
											2012-10-24 12:57:48 +00:00
										 |  |  | 				break; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		/* if not internally connected, assign a new stack index anyway to avoid bad stack access */ | 
					
						
							| 
									
										
										
										
											2013-03-18 16:34:57 +00:00
										 |  |  | 		if (!link) { | 
					
						
							|  |  |  | 			if (node_exec_socket_use_stack(sock)) | 
					
						
							|  |  |  | 				sock->stack_index = (*index)++; | 
					
						
							|  |  |  | 			else | 
					
						
							|  |  |  | 				sock->stack_index = -1; | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2012-10-24 12:57:48 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 	else { | 
					
						
							| 
									
										
										
										
											2013-03-18 16:34:57 +00:00
										 |  |  | 		if (node_exec_socket_use_stack(sock)) | 
					
						
							|  |  |  | 			sock->stack_index = (*index)++; | 
					
						
							|  |  |  | 		else | 
					
						
							|  |  |  | 			sock->stack_index = -1; | 
					
						
							| 
									
										
										
										
											2012-10-24 12:57:48 +00:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2011-09-05 21:01:50 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* basic preparation of socket stacks */ | 
					
						
							| 
									
										
										
										
											2013-03-18 16:34:57 +00:00
										 |  |  | static struct bNodeStack *setup_stack(bNodeStack *stack, bNodeTree *ntree, bNode *node, bNodeSocket *sock) | 
					
						
							| 
									
										
										
										
											2011-09-05 21:01:50 +00:00
										 |  |  | { | 
					
						
							|  |  |  | 	bNodeStack *ns = node_get_socket_stack(stack, sock); | 
					
						
							| 
									
										
										
										
											2013-03-18 16:34:57 +00:00
										 |  |  | 	if (!ns) | 
					
						
							|  |  |  | 		return NULL; | 
					
						
							| 
									
										
										
										
											2018-06-08 08:07:48 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-09-05 21:01:50 +00:00
										 |  |  | 	/* don't mess with remote socket stacks, these are initialized by other nodes! */ | 
					
						
							|  |  |  | 	if (sock->link) | 
					
						
							|  |  |  | 		return ns; | 
					
						
							| 
									
										
										
										
											2018-06-08 08:07:48 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-09-05 21:01:50 +00:00
										 |  |  | 	ns->sockettype = sock->type; | 
					
						
							| 
									
										
										
										
											2018-06-08 08:07:48 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-03-18 16:34:57 +00:00
										 |  |  | 	switch (sock->type) { | 
					
						
							| 
									
										
										
										
											2011-09-05 21:01:50 +00:00
										 |  |  | 		case SOCK_FLOAT: | 
					
						
							| 
									
										
										
										
											2013-03-18 16:34:57 +00:00
										 |  |  | 			ns->vec[0] = node_socket_get_float(ntree, node, sock); | 
					
						
							| 
									
										
										
										
											2011-09-05 21:01:50 +00:00
										 |  |  | 			break; | 
					
						
							|  |  |  | 		case SOCK_VECTOR: | 
					
						
							| 
									
										
										
										
											2013-03-18 16:34:57 +00:00
										 |  |  | 			node_socket_get_vector(ntree, node, sock, ns->vec); | 
					
						
							| 
									
										
										
										
											2011-09-05 21:01:50 +00:00
										 |  |  | 			break; | 
					
						
							|  |  |  | 		case SOCK_RGBA: | 
					
						
							| 
									
										
										
										
											2013-03-18 16:34:57 +00:00
										 |  |  | 			node_socket_get_color(ntree, node, sock, ns->vec); | 
					
						
							| 
									
										
										
										
											2011-09-05 21:01:50 +00:00
										 |  |  | 			break; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2018-06-08 08:07:48 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-09-05 21:01:50 +00:00
										 |  |  | 	return ns; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-03-18 16:34:57 +00:00
										 |  |  | bNodeTreeExec *ntree_exec_begin(bNodeExecContext *context, bNodeTree *ntree, bNodeInstanceKey parent_key) | 
					
						
							| 
									
										
										
										
											2011-09-05 21:01:50 +00:00
										 |  |  | { | 
					
						
							|  |  |  | 	bNodeTreeExec *exec; | 
					
						
							|  |  |  | 	bNode *node; | 
					
						
							|  |  |  | 	bNodeExec *nodeexec; | 
					
						
							| 
									
										
										
										
											2013-03-18 16:34:57 +00:00
										 |  |  | 	bNodeInstanceKey nodekey; | 
					
						
							|  |  |  | 	bNodeSocket *sock; | 
					
						
							| 
									
										
										
										
											2011-09-05 21:01:50 +00:00
										 |  |  | 	bNodeStack *ns; | 
					
						
							| 
									
										
										
										
											2012-10-24 12:57:48 +00:00
										 |  |  | 	int index; | 
					
						
							| 
									
										
										
										
											2011-09-05 21:01:50 +00:00
										 |  |  | 	bNode **nodelist; | 
					
						
							|  |  |  | 	int totnodes, n; | 
					
						
							| 
									
										
										
										
											2014-08-12 12:41:26 +02:00
										 |  |  | 	/* XXX texnodes have threading issues with muting, have to disable it there ... */ | 
					
						
							| 
									
										
										
										
											2018-06-08 08:07:48 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-03-18 16:34:57 +00:00
										 |  |  | 	/* ensure all sock->link pointers and node levels are correct */ | 
					
						
							| 
									
										
										
										
											2018-06-25 12:02:20 +02:00
										 |  |  | 	/* Using global main here is likely totally wrong, not sure what to do about that one though...
 | 
					
						
							|  |  |  | 	 * We cannot even check ntree is in global main, since most of the time it won't be (thanks to ntree design)!!! */ | 
					
						
							| 
									
										
										
										
											2013-05-07 15:28:42 +00:00
										 |  |  | 	ntreeUpdateTree(G.main, ntree); | 
					
						
							| 
									
										
										
										
											2018-06-08 08:07:48 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-09-05 21:01:50 +00:00
										 |  |  | 	/* get a dependency-sorted list of nodes */ | 
					
						
							|  |  |  | 	ntreeGetDependencyList(ntree, &nodelist, &totnodes); | 
					
						
							| 
									
										
										
										
											2018-06-08 08:07:48 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-09-05 21:01:50 +00:00
										 |  |  | 	/* XXX could let callbacks do this for specialized data */ | 
					
						
							|  |  |  | 	exec = MEM_callocN(sizeof(bNodeTreeExec), "node tree execution data"); | 
					
						
							|  |  |  | 	/* backpointer to node tree */ | 
					
						
							|  |  |  | 	exec->nodetree = ntree; | 
					
						
							| 
									
										
										
										
											2018-06-08 08:07:48 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-10-24 12:57:48 +00:00
										 |  |  | 	/* set stack indices */ | 
					
						
							|  |  |  | 	index = 0; | 
					
						
							| 
									
										
										
										
											2013-05-27 08:04:07 +00:00
										 |  |  | 	for (n = 0; n < totnodes; ++n) { | 
					
						
							| 
									
										
										
										
											2011-09-05 21:01:50 +00:00
										 |  |  | 		node = nodelist[n]; | 
					
						
							| 
									
										
										
										
											2018-06-08 08:07:48 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-09-05 21:01:50 +00:00
										 |  |  | 		node->stack_index = index; | 
					
						
							| 
									
										
										
										
											2018-06-08 08:07:48 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-09-05 21:01:50 +00:00
										 |  |  | 		/* init node socket stack indexes */ | 
					
						
							| 
									
										
										
										
											2013-03-18 18:25:05 +00:00
										 |  |  | 		for (sock = node->inputs.first; sock; sock = sock->next) | 
					
						
							| 
									
										
										
										
											2011-09-05 21:01:50 +00:00
										 |  |  | 			node_init_input_index(sock, &index); | 
					
						
							| 
									
										
										
										
											2018-06-08 08:07:48 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-09-17 18:27:05 +02:00
										 |  |  | 		if (node->flag & NODE_MUTED || node->type == NODE_REROUTE) { | 
					
						
							| 
									
										
										
										
											2013-03-18 18:25:05 +00:00
										 |  |  | 			for (sock = node->outputs.first; sock; sock = sock->next) | 
					
						
							| 
									
										
										
										
											2012-10-25 16:49:06 +00:00
										 |  |  | 				node_init_output_index(sock, &index, &node->internal_links); | 
					
						
							| 
									
										
										
										
											2012-10-24 12:57:48 +00:00
										 |  |  | 		} | 
					
						
							|  |  |  | 		else { | 
					
						
							| 
									
										
										
										
											2013-03-18 18:25:05 +00:00
										 |  |  | 			for (sock = node->outputs.first; sock; sock = sock->next) | 
					
						
							| 
									
										
										
										
											2012-10-24 12:57:48 +00:00
										 |  |  | 				node_init_output_index(sock, &index, NULL); | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2011-09-05 21:01:50 +00:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2018-06-08 08:07:48 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-09-05 21:01:50 +00:00
										 |  |  | 	/* allocated exec data pointers for nodes */ | 
					
						
							|  |  |  | 	exec->totnodes = totnodes; | 
					
						
							|  |  |  | 	exec->nodeexec = MEM_callocN(exec->totnodes * sizeof(bNodeExec), "node execution data"); | 
					
						
							|  |  |  | 	/* allocate data pointer for node stack */ | 
					
						
							|  |  |  | 	exec->stacksize = index; | 
					
						
							|  |  |  | 	exec->stack = MEM_callocN(exec->stacksize * sizeof(bNodeStack), "bNodeStack"); | 
					
						
							| 
									
										
										
										
											2018-06-08 08:07:48 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-10-12 12:55:32 +00:00
										 |  |  | 	/* all non-const results are considered inputs */ | 
					
						
							| 
									
										
										
										
											2013-05-27 08:04:07 +00:00
										 |  |  | 	for (n = 0; n < exec->stacksize; ++n) | 
					
						
							| 
									
										
										
										
											2011-10-12 12:55:32 +00:00
										 |  |  | 		exec->stack[n].hasinput = 1; | 
					
						
							| 
									
										
										
										
											2018-06-08 08:07:48 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-03-18 16:34:57 +00:00
										 |  |  | 	/* prepare all nodes for execution */ | 
					
						
							| 
									
										
										
										
											2013-05-27 08:04:07 +00:00
										 |  |  | 	for (n = 0, nodeexec = exec->nodeexec; n < totnodes; ++n, ++nodeexec) { | 
					
						
							| 
									
										
										
										
											2011-09-05 21:01:50 +00:00
										 |  |  | 		node = nodeexec->node = nodelist[n]; | 
					
						
							| 
									
										
										
										
											2013-10-29 17:46:01 +00:00
										 |  |  | 		nodeexec->freeexecfunc = node->typeinfo->freeexecfunc; | 
					
						
							| 
									
										
										
										
											2018-06-08 08:07:48 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-09-05 21:01:50 +00:00
										 |  |  | 		/* tag inputs */ | 
					
						
							| 
									
										
										
										
											2013-03-18 18:25:05 +00:00
										 |  |  | 		for (sock = node->inputs.first; sock; sock = sock->next) { | 
					
						
							| 
									
										
										
										
											2011-09-05 21:01:50 +00:00
										 |  |  | 			/* disable the node if an input link is invalid */ | 
					
						
							| 
									
										
										
										
											2012-03-24 06:38:07 +00:00
										 |  |  | 			if (sock->link && !(sock->link->flag & NODE_LINK_VALID)) | 
					
						
							| 
									
										
										
										
											2013-05-27 08:04:07 +00:00
										 |  |  | 				node->need_exec = 0; | 
					
						
							| 
									
										
										
										
											2018-06-08 08:07:48 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-03-18 16:34:57 +00:00
										 |  |  | 			ns = setup_stack(exec->stack, ntree, node, sock); | 
					
						
							|  |  |  | 			if (ns) | 
					
						
							|  |  |  | 				ns->hasoutput = 1; | 
					
						
							| 
									
										
										
										
											2011-09-05 21:01:50 +00:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2018-06-08 08:07:48 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-09-05 21:01:50 +00:00
										 |  |  | 		/* tag all outputs */ | 
					
						
							| 
									
										
										
										
											2013-03-18 18:25:05 +00:00
										 |  |  | 		for (sock = node->outputs.first; sock; sock = sock->next) { | 
					
						
							| 
									
										
										
										
											2013-03-18 16:34:57 +00:00
										 |  |  | 			/* ns = */ setup_stack(exec->stack, ntree, node, sock); | 
					
						
							| 
									
										
										
										
											2011-09-05 21:01:50 +00:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2018-06-08 08:07:48 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-03-18 16:34:57 +00:00
										 |  |  | 		nodekey = BKE_node_instance_key(parent_key, ntree, node); | 
					
						
							|  |  |  | 		nodeexec->data.preview = context->previews ? BKE_node_instance_hash_lookup(context->previews, nodekey) : NULL; | 
					
						
							| 
									
										
										
										
											2012-03-24 06:38:07 +00:00
										 |  |  | 		if (node->typeinfo->initexecfunc) | 
					
						
							| 
									
										
										
										
											2013-03-18 16:34:57 +00:00
										 |  |  | 			nodeexec->data.data = node->typeinfo->initexecfunc(context, node, nodekey); | 
					
						
							| 
									
										
										
										
											2011-09-05 21:01:50 +00:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2018-06-08 08:07:48 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-09-05 21:01:50 +00:00
										 |  |  | 	if (nodelist) | 
					
						
							|  |  |  | 		MEM_freeN(nodelist); | 
					
						
							| 
									
										
										
										
											2018-06-08 08:07:48 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-09-05 21:01:50 +00:00
										 |  |  | 	return exec; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void ntree_exec_end(bNodeTreeExec *exec) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	bNodeExec *nodeexec; | 
					
						
							|  |  |  | 	int n; | 
					
						
							| 
									
										
										
										
											2018-06-08 08:07:48 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-09-05 21:01:50 +00:00
										 |  |  | 	if (exec->stack) | 
					
						
							|  |  |  | 		MEM_freeN(exec->stack); | 
					
						
							| 
									
										
										
										
											2018-06-08 08:07:48 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-05-27 08:04:07 +00:00
										 |  |  | 	for (n = 0, nodeexec = exec->nodeexec; n < exec->totnodes; ++n, ++nodeexec) { | 
					
						
							| 
									
										
										
										
											2013-10-29 17:46:01 +00:00
										 |  |  | 		if (nodeexec->freeexecfunc) | 
					
						
							|  |  |  | 			nodeexec->freeexecfunc(nodeexec->data.data); | 
					
						
							| 
									
										
										
										
											2011-09-05 21:01:50 +00:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2018-06-08 08:07:48 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-09-05 21:01:50 +00:00
										 |  |  | 	if (exec->nodeexec) | 
					
						
							|  |  |  | 		MEM_freeN(exec->nodeexec); | 
					
						
							| 
									
										
										
										
											2018-06-08 08:07:48 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-09-05 21:01:50 +00:00
										 |  |  | 	MEM_freeN(exec); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-01-15 12:16:44 +00:00
										 |  |  | /**** Material/Texture trees ****/ | 
					
						
							| 
									
										
										
										
											2011-09-05 21:01:50 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | bNodeThreadStack *ntreeGetThreadStack(bNodeTreeExec *exec, int thread) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2013-05-27 08:04:07 +00:00
										 |  |  | 	ListBase *lb = &exec->threadstack[thread]; | 
					
						
							| 
									
										
										
										
											2011-09-05 21:01:50 +00:00
										 |  |  | 	bNodeThreadStack *nts; | 
					
						
							| 
									
										
										
										
											2018-06-08 08:07:48 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-05-27 08:04:07 +00:00
										 |  |  | 	for (nts = lb->first; nts; nts = nts->next) { | 
					
						
							| 
									
										
										
										
											2012-03-24 06:38:07 +00:00
										 |  |  | 		if (!nts->used) { | 
					
						
							| 
									
										
										
										
											2014-04-01 11:34:00 +11:00
										 |  |  | 			nts->used = true; | 
					
						
							| 
									
										
										
										
											2011-09-05 21:01:50 +00:00
										 |  |  | 			break; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2018-06-08 08:07:48 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-09-05 21:01:50 +00:00
										 |  |  | 	if (!nts) { | 
					
						
							| 
									
										
										
										
											2013-05-27 08:04:07 +00:00
										 |  |  | 		nts = MEM_callocN(sizeof(bNodeThreadStack), "bNodeThreadStack"); | 
					
						
							|  |  |  | 		nts->stack = MEM_dupallocN(exec->stack); | 
					
						
							| 
									
										
										
										
											2014-04-01 11:34:00 +11:00
										 |  |  | 		nts->used = true; | 
					
						
							| 
									
										
										
										
											2011-09-05 21:01:50 +00:00
										 |  |  | 		BLI_addtail(lb, nts); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return nts; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void ntreeReleaseThreadStack(bNodeThreadStack *nts) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	nts->used = 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-01-24 21:57:13 +00:00
										 |  |  | bool ntreeExecThreadNodes(bNodeTreeExec *exec, bNodeThreadStack *nts, void *callerdata, int thread) | 
					
						
							| 
									
										
										
										
											2011-09-05 21:01:50 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2013-09-12 01:41:16 +00:00
										 |  |  | 	bNodeStack *nsin[MAX_SOCKET] = {NULL};   /* arbitrary... watch this */ | 
					
						
							|  |  |  | 	bNodeStack *nsout[MAX_SOCKET] = {NULL};  /* arbitrary... watch this */ | 
					
						
							| 
									
										
										
										
											2011-09-05 21:01:50 +00:00
										 |  |  | 	bNodeExec *nodeexec; | 
					
						
							|  |  |  | 	bNode *node; | 
					
						
							|  |  |  | 	int n; | 
					
						
							| 
									
										
										
										
											2018-06-08 08:07:48 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-09-05 21:01:50 +00:00
										 |  |  | 	/* nodes are presorted, so exec is in order of list */ | 
					
						
							| 
									
										
										
										
											2018-06-08 08:07:48 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-05-27 08:04:07 +00:00
										 |  |  | 	for (n = 0, nodeexec = exec->nodeexec; n < exec->totnodes; ++n, ++nodeexec) { | 
					
						
							| 
									
										
										
										
											2011-09-05 21:01:50 +00:00
										 |  |  | 		node = nodeexec->node; | 
					
						
							| 
									
										
										
										
											2012-03-24 06:38:07 +00:00
										 |  |  | 		if (node->need_exec) { | 
					
						
							| 
									
										
										
										
											2011-09-05 21:01:50 +00:00
										 |  |  | 			node_get_stack(node, nts->stack, nsin, nsout); | 
					
						
							| 
									
										
										
										
											2011-11-20 16:38:23 +00:00
										 |  |  | 			/* Handle muted nodes...
 | 
					
						
							|  |  |  | 			 * If the mute func is not set, assume the node should never be muted, | 
					
						
							|  |  |  | 			 * and hence execute it! | 
					
						
							|  |  |  | 			 */ | 
					
						
							| 
									
										
										
										
											2013-01-24 19:31:44 +00:00
										 |  |  | //			if (node->typeinfo->compatibility == NODE_NEW_SHADING)
 | 
					
						
							| 
									
										
										
										
											2013-01-24 21:57:13 +00:00
										 |  |  | //				return false;
 | 
					
						
							| 
									
										
										
										
											2014-09-24 14:27:36 +02:00
										 |  |  | 			if (node->typeinfo->execfunc && !(node->flag & NODE_MUTED)) | 
					
						
							| 
									
										
										
										
											2013-03-18 16:34:57 +00:00
										 |  |  | 				node->typeinfo->execfunc(callerdata, thread, node, &nodeexec->data, nsin, nsout); | 
					
						
							| 
									
										
										
										
											2011-09-05 21:01:50 +00:00
										 |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2018-06-08 08:07:48 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-01-24 18:56:04 +00:00
										 |  |  | 	/* signal to that all went OK, for render */ | 
					
						
							| 
									
										
										
										
											2013-01-24 21:57:13 +00:00
										 |  |  | 	return true; | 
					
						
							| 
									
										
										
										
											2011-09-05 21:01:50 +00:00
										 |  |  | } |