Esempio n. 1
0
static void *exec_composite_node(void *nodeexec_v)
{
	bNodeStack *nsin[MAX_SOCKET];	/* arbitrary... watch this */
	bNodeStack *nsout[MAX_SOCKET];	/* arbitrary... watch this */
	bNodeExec *nodeexec= nodeexec_v;
	bNode *node= nodeexec->node;
	ThreadData *thd= (ThreadData *)node->threaddata;
	
	node_get_stack(node, thd->stack, nsin, nsout);
	
	if((node->flag & NODE_MUTED) && (!node_only_value(node))) {
		/* viewers we execute, for feedback to user */
		if(ELEM(node->type, CMP_NODE_VIEWER, CMP_NODE_SPLITVIEWER)) 
			node->typeinfo->execfunc(thd->rd, node, nsin, nsout);
		else
			node_compo_pass_on(node, nsin, nsout);
	}
	else if(node->typeinfo->execfunc)
		node->typeinfo->execfunc(thd->rd, node, nsin, nsout);
	else if (node->typeinfo->newexecfunc)
		node->typeinfo->newexecfunc(thd->rd, 0, node, nodeexec->data, nsin, nsout);
	
	node->exec |= NODE_READY;
	return NULL;
}
Esempio n. 2
0
bool ntreeExecThreadNodes(bNodeTreeExec *exec, bNodeThreadStack *nts, void *callerdata, int thread)
{
	bNodeStack *nsin[MAX_SOCKET];	/* arbitrary... watch this */
	bNodeStack *nsout[MAX_SOCKET];	/* arbitrary... watch this */
	bNodeExec *nodeexec;
	bNode *node;
	int n;
	
	/* nodes are presorted, so exec is in order of list */
	
	for (n=0, nodeexec= exec->nodeexec; n < exec->totnodes; ++n, ++nodeexec) {
		node = nodeexec->node;
		if (node->need_exec) {
			node_get_stack(node, nts->stack, nsin, nsout);
			/* Handle muted nodes...
			 * If the mute func is not set, assume the node should never be muted,
			 * and hence execute it!
			 */
//			if (node->typeinfo->compatibility == NODE_NEW_SHADING)
//				return false;
			if (node->typeinfo->execfunc)
				node->typeinfo->execfunc(callerdata, thread, node, &nodeexec->data, nsin, nsout);
		}
	}
	
	/* signal to that all went OK, for render */
	return true;
}
static void *exec_composite_node(void *nodeexec_v)
{
	bNodeStack *nsin[MAX_SOCKET];	/* arbitrary... watch this */
	bNodeStack *nsout[MAX_SOCKET];	/* arbitrary... watch this */
	bNodeExec *nodeexec= nodeexec_v;
	bNode *node= nodeexec->node;
	ThreadData *thd= (ThreadData *)node->threaddata;
	
	node_get_stack(node, thd->stack, nsin, nsout);
	
	if (node->typeinfo->execfunc)
		node->typeinfo->execfunc(thd->rd, node, nsin, nsout);
	else if (node->typeinfo->newexecfunc)
		node->typeinfo->newexecfunc(thd->rd, 0, node, nodeexec->data, nsin, nsout);
	
	node->exec |= NODE_READY;
	return NULL;
}
Esempio n. 4
0
void ntreeExecThreadNodes(bNodeTreeExec *exec, bNodeThreadStack *nts, void *callerdata, int thread)
{
	bNodeStack *nsin[MAX_SOCKET];	/* arbitrary... watch this */
	bNodeStack *nsout[MAX_SOCKET];	/* arbitrary... watch this */
	bNodeExec *nodeexec;
	bNode *node;
	int n;
	
	/* nodes are presorted, so exec is in order of list */
	
	for(n=0, nodeexec= exec->nodeexec; n < exec->totnodes; ++n, ++nodeexec) {
		node = nodeexec->node;
		if(node->need_exec) {
			node_get_stack(node, nts->stack, nsin, nsout);
			if(node->typeinfo->execfunc)
				node->typeinfo->execfunc(callerdata, node, nsin, nsout);
			else if (node->typeinfo->newexecfunc)
				node->typeinfo->newexecfunc(callerdata, thread, node, nodeexec->data, nsin, nsout);
		}
	}
}
void ntreeExecGPUNodes(bNodeTreeExec *exec, GPUMaterial *mat, int do_outputs, short compatibility)
{
	bNodeExec *nodeexec;
	bNode *node;
	int n;
	bNodeStack *stack;
	bNodeStack *nsin[MAX_SOCKET];   /* arbitrary... watch this */
	bNodeStack *nsout[MAX_SOCKET];  /* arbitrary... watch this */
	GPUNodeStack gpuin[MAX_SOCKET + 1], gpuout[MAX_SOCKET + 1];
	bool do_it;

	stack = exec->stack;

	for (n = 0, nodeexec = exec->nodeexec; n < exec->totnodes; ++n, ++nodeexec) {
		node = nodeexec->node;
		
		do_it = false;
		/* for groups, only execute outputs for edited group */
		if (node->typeinfo->nclass == NODE_CLASS_OUTPUT) {
			if (node->typeinfo->compatibility & compatibility)
				if (do_outputs && (node->flag & NODE_DO_OUTPUT))
					do_it = true;
		}
		else {
			do_it = true;
		}

		if (do_it) {
			if (node->typeinfo->gpufunc) {
				node_get_stack(node, stack, nsin, nsout);
				gpu_stack_from_data_list(gpuin, &node->inputs, nsin);
				gpu_stack_from_data_list(gpuout, &node->outputs, nsout);
				if (node->typeinfo->gpufunc(mat, node, &nodeexec->data, gpuin, gpuout))
					data_from_gpu_stack_list(&node->outputs, nsout, gpuout);
			}
		}
	}
}
/* return total of executable nodes, for timecursor */
static int setExecutableNodes(bNodeTreeExec *exec, ThreadData *thd)
{
	bNodeTree *ntree = exec->nodetree;
	bNodeStack *nsin[MAX_SOCKET];	/* arbitrary... watch this */
	bNodeStack *nsout[MAX_SOCKET];	/* arbitrary... watch this */
	bNodeExec *nodeexec;
	bNode *node;
	bNodeSocket *sock;
	int n, totnode= 0, group_edit= 0;
	
	/* if we are in group edit, viewer nodes get skipped when group has viewer */
	for (node= ntree->nodes.first; node; node= node->next)
		if (node->type==NODE_GROUP && (node->flag & NODE_GROUP_EDIT))
			if (ntreeHasType((bNodeTree *)node->id, CMP_NODE_VIEWER))
				group_edit= 1;
	
	/* NB: using the exec data list here to have valid dependency sort */
	for (n=0, nodeexec=exec->nodeexec; n < exec->totnodes; ++n, ++nodeexec) {
		int a;
		node = nodeexec->node;
		
		node_get_stack(node, exec->stack, nsin, nsout);
		
		/* test the outputs */
		/* skip value-only nodes (should be in type!) */
		if (!node_only_value(node)) {
			for (a=0, sock= node->outputs.first; sock; sock= sock->next, a++) {
				if (nsout[a]->data==NULL && nsout[a]->hasoutput) {
					node->need_exec= 1;
					break;
				}
			}
		}
		
		/* test the inputs */
		for (a=0, sock= node->inputs.first; sock; sock= sock->next, a++) {
			/* skip viewer nodes in bg render or group edit */
			if ( ELEM(node->type, CMP_NODE_VIEWER, CMP_NODE_SPLITVIEWER) && (G.background || group_edit))
				node->need_exec= 0;
			/* is sock in use? */
			else if (sock->link) {
				bNodeLink *link= sock->link;
				
				/* this is the test for a cyclic case */
				if (link->fromnode==NULL || link->tonode==NULL);
				else if (link->fromnode->level >= link->tonode->level && link->tonode->level!=0xFFF) {
					if (link->fromnode->need_exec) {
						node->need_exec= 1;
						break;
					}
				}
				else {
					node->need_exec= 0;
					printf("Node %s skipped, cyclic dependency\n", node->name);
				}
			}
		}
		
		if (node->need_exec) {
			
			/* free output buffers */
			for (a=0, sock= node->outputs.first; sock; sock= sock->next, a++) {
				if (nsout[a]->data) {
					free_compbuf(nsout[a]->data);
					nsout[a]->data= NULL;
				}
			}
			totnode++;
			/* printf("node needs exec %s\n", node->name); */
			
			/* tag for getExecutableNode() */
			node->exec= 0;
		}
		else {
			/* tag for getExecutableNode() */
			node->exec= NODE_READY|NODE_FINISHED|NODE_SKIPPED;
			
		}
	}
	
	/* last step: set the stack values for only-value nodes */
	/* just does all now, compared to a full buffer exec this is nothing */
	if (totnode) {
		for (n=0, nodeexec=exec->nodeexec; n < exec->totnodes; ++n, ++nodeexec) {
			node = nodeexec->node;
			if (node->need_exec==0 && node_only_value(node)) {
				if (node->typeinfo->execfunc) {
					node_get_stack(node, exec->stack, nsin, nsout);
					node->typeinfo->execfunc(thd->rd, node, nsin, nsout);
				}
			}
		}
	}
	
	return totnode;
}