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); } } }
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; }