void ExecutionSystemHelper::addbNodeTree(ExecutionSystem &system, int nodes_start, bNodeTree *tree, bNodeInstanceKey parent_key)
{
	vector<Node *>& nodes = system.getNodes();
	vector<SocketConnection *>& links = system.getConnections();
	
	const bNodeTree *basetree = system.getContext().getbNodeTree();
	/* update viewers in the active edittree as well the base tree (for backdrop) */
	bool is_active_group = ((parent_key.value == basetree->active_viewer_key.value) ||
	                        (tree == basetree));
	
	/* add all nodes of the tree to the node list */
	bNode *node = (bNode *)tree->nodes.first;
	while (node != NULL) {
		Node *nnode = addNode(nodes, node, is_active_group, system.getContext().isFastCalculation());
		if (nnode) {
			nnode->setbNodeTree(tree);
			nnode->setInstanceKey(BKE_node_instance_key(parent_key, tree, node));
		}
		node = node->next;
	}

	NodeRange node_range(nodes.begin() + nodes_start, nodes.end());

	/* add all nodelinks of the tree to the link list */
	bNodeLink *nodelink = (bNodeLink *)tree->links.first;
	while (nodelink != NULL) {
		addNodeLink(node_range, links, nodelink);
		nodelink = nodelink->next;
	}

	/* Expand group nodes
	 * Only go up to nodes_end, to avoid ungrouping nested node groups repeatedly.
	 */
	int nodes_end = nodes.size();
	for (unsigned int i = nodes_start; i < nodes_end; ++i) {
		Node *execnode = nodes[i];
		if (execnode->isGroupNode()) {
			GroupNode *groupNode = (GroupNode *)execnode;
			groupNode->ungroup(system);
		}
	}
}
Exemple #2
0
bNodeTreeExec *ntree_exec_begin(bNodeExecContext *context, bNodeTree *ntree, bNodeInstanceKey parent_key)
{
	bNodeTreeExec *exec;
	bNode *node;
	bNodeExec *nodeexec;
	bNodeInstanceKey nodekey;
	bNodeSocket *sock;
	bNodeStack *ns;
	int index;
	bNode **nodelist;
	int totnodes, n;
	
	/* ensure all sock->link pointers and node levels are correct */
	ntreeUpdateTree(G.main, ntree);
	
	/* get a dependency-sorted list of nodes */
	ntreeGetDependencyList(ntree, &nodelist, &totnodes);
	
	/* 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;
	
	/* set stack indices */
	index = 0;
	for (n=0; n < totnodes; ++n) {
		node = nodelist[n];
		
		node->stack_index = index;
		
		/* init node socket stack indexes */
		for (sock = node->inputs.first; sock; sock = sock->next)
			node_init_input_index(sock, &index);
		
		if (node->flag & NODE_MUTED || node->type == NODE_REROUTE) {
			for (sock = node->outputs.first; sock; sock = sock->next)
				node_init_output_index(sock, &index, &node->internal_links);
		}
		else {
			for (sock = node->outputs.first; sock; sock = sock->next)
				node_init_output_index(sock, &index, NULL);
		}
	}
	
	/* 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");
	
	/* all non-const results are considered inputs */
	for (n=0; n < exec->stacksize; ++n)
		exec->stack[n].hasinput = 1;
	
	/* prepare all nodes for execution */
	for (n=0, nodeexec= exec->nodeexec; n < totnodes; ++n, ++nodeexec) {
		node = nodeexec->node = nodelist[n];
		
		/* tag inputs */
		for (sock = node->inputs.first; sock; sock = sock->next) {
			/* disable the node if an input link is invalid */
			if (sock->link && !(sock->link->flag & NODE_LINK_VALID))
				node->need_exec= 0;
			
			ns = setup_stack(exec->stack, ntree, node, sock);
			if (ns)
				ns->hasoutput = 1;
		}
		
		/* tag all outputs */
		for (sock = node->outputs.first; sock; sock = sock->next) {
			/* ns = */ setup_stack(exec->stack, ntree, node, sock);
		}
		
		nodekey = BKE_node_instance_key(parent_key, ntree, node);
		nodeexec->data.preview = context->previews ? BKE_node_instance_hash_lookup(context->previews, nodekey) : NULL;
		if (node->typeinfo->initexecfunc)
			nodeexec->data.data = node->typeinfo->initexecfunc(context, node, nodekey);
	}
	
	if (nodelist)
		MEM_freeN(nodelist);
	
	return exec;
}