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; }
static int node_select_same_type_step_exec(bContext *C, wmOperator *op) { SpaceNode *snode = CTX_wm_space_node(C); ARegion *ar = CTX_wm_region(C); bNode **node_array; bNode *active = nodeGetActive(snode->edittree); int totnodes; const bool revert = RNA_boolean_get(op->ptr, "prev"); const bool same_type = 1; ntreeGetDependencyList(snode->edittree, &node_array, &totnodes); if (totnodes > 1) { int a; for (a = 0; a < totnodes; a++) { if (node_array[a] == active) break; } if (same_type) { bNode *node = NULL; while (node == NULL) { if (revert) a--; else a++; if (a < 0 || a >= totnodes) break; node = node_array[a]; if (node->type == active->type) break; else node = NULL; } if (node) active = node; } else { if (revert) { if (a == 0) active = node_array[totnodes - 1]; else active = node_array[a - 1]; } else { if (a == totnodes - 1) active = node_array[0]; else active = node_array[a + 1]; } } node_select_single(C, active); /* is note outside view? */ if (active->totr.xmax < ar->v2d.cur.xmin || active->totr.xmin > ar->v2d.cur.xmax || active->totr.ymax < ar->v2d.cur.ymin || active->totr.ymin > ar->v2d.cur.ymax) { const int smooth_viewtx = WM_operator_smooth_viewtx_get(op); space_node_view_flag(C, snode, ar, NODE_SELECT, smooth_viewtx); } } if (node_array) MEM_freeN(node_array); return OPERATOR_FINISHED; }
bNodeTreeExec *ntree_exec_begin(bNodeTree *ntree) { bNodeTreeExec *exec; bNode *node; bNodeExec *nodeexec; bNodeSocket *sock, *gsock; bNodeStack *ns; int index= 0; bNode **nodelist; int totnodes, n; if((ntree->init & NTREE_TYPE_INIT)==0) ntreeInitTypes(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; /* group inputs essentially work as outputs */ for(gsock=ntree->inputs.first; gsock; gsock = gsock->next) node_init_output_index(gsock, &index); /* set stack indexes */ 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); for (sock=node->outputs.first; sock; sock=sock->next) node_init_output_index(sock, &index); } /* group outputs essentially work as inputs */ for(gsock=ntree->outputs.first; gsock; gsock = gsock->next) node_init_input_index(gsock, &index); /* 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 group tree inputs */ for (sock=ntree->inputs.first; sock; sock=sock->next) { /* ns = */ setup_stack(exec->stack, sock); } /* prepare all internal 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, sock); ns->hasoutput = 1; } /* tag all outputs */ for (sock=node->outputs.first; sock; sock=sock->next) { /* ns = */ setup_stack(exec->stack, sock); } if(node->typeinfo->initexecfunc) nodeexec->data = node->typeinfo->initexecfunc(node); } /* prepare group tree outputs */ for (sock=ntree->outputs.first; sock; sock=sock->next) { ns = setup_stack(exec->stack, sock); ns->hasoutput = 1; } if (nodelist) MEM_freeN(nodelist); return exec; }