static int node_tree_has_type(int treetype, int nodetype) { bNodeTreeType *ttype= ntreeGetType(treetype); bNodeType *ntype; for (ntype=ttype->node_types.first; ntype; ntype=ntype->next) { if (ntype->type==nodetype) return 1; } return 0; }
static void node_add_menu(bContext *C, uiLayout *layout, void *arg_nodeclass) { Main *bmain = CTX_data_main(C); Scene *scene = CTX_data_scene(C); SpaceNode *snode = CTX_wm_space_node(C); bNodeTree *ntree; int nodeclass = GET_INT_FROM_POINTER(arg_nodeclass); int event, compatibility = 0; ntree = snode->nodetree; if (!ntree) { uiItemS(layout); return; } if (ntree->type == NTREE_SHADER) { if (BKE_scene_use_new_shading_nodes(scene)) compatibility = NODE_NEW_SHADING; else compatibility = NODE_OLD_SHADING; } if (nodeclass == NODE_CLASS_GROUP) { bNodeTree *ngroup; uiLayoutSetFunc(layout, do_node_add_group, NULL); /* XXX hack: negative numbers used for empty group types */ if (node_tree_has_type(ntree->type, NODE_GROUP)) uiItemV(layout, IFACE_("New Group"), 0, -NODE_GROUP); uiItemS(layout); for (ngroup = bmain->nodetree.first, event = 0; ngroup; ngroup = ngroup->id.next, ++event) { /* only use group trees */ if (ngroup->type == ntree->type && ngroup->nodetype == NODE_GROUP) { uiItemV(layout, ngroup->id.name + 2, 0, event); } } } else { bNodeType *ntype; uiLayoutSetFunc(layout, do_node_add_static, NULL); for (ntype = ntreeGetType(ntree->type)->node_types.first; ntype; ntype = ntype->next) { if (ntype->nclass == nodeclass && ntype->name) { if (!compatibility || (ntype->compatibility & compatibility)) { uiItemV(layout, IFACE_(ntype->name), 0, ntype->type); } } } } }
void ED_node_generic_update(Main *bmain, bNodeTree *ntree, bNode *node) { bNodeTreeType *tti= ntreeGetType(ntree->type); NodeUpdateCalldata cd; cd.ntree = ntree; cd.node = node; /* look through all datablocks, to support groups */ tti->foreach_nodetree(bmain, &cd, node_generic_update_cb); if(ntree->type == NTREE_TEXTURE) ntreeTexCheckCyclics(ntree); }
static void node_add_menu(bContext *C, uiLayout *layout, void *arg_nodeclass) { Main *bmain= CTX_data_main(C); SpaceNode *snode= CTX_wm_space_node(C); bNodeTree *ntree; int nodeclass= GET_INT_FROM_POINTER(arg_nodeclass); int event; ntree = snode->nodetree; if(!ntree) { uiItemS(layout); return; } if (nodeclass==NODE_CLASS_GROUP) { bNodeTree *ngroup; uiLayoutSetFunc(layout, do_node_add_group, NULL); /* XXX hack: negative numbers used for empty group types */ if (node_tree_has_type(ntree->type, NODE_GROUP)) uiItemV(layout, "New Group", 0, -NODE_GROUP); if (node_tree_has_type(ntree->type, NODE_FORLOOP)) uiItemV(layout, "New For Loop", 0, -NODE_FORLOOP); if (node_tree_has_type(ntree->type, NODE_WHILELOOP)) uiItemV(layout, "New While Loop", 0, -NODE_WHILELOOP); uiItemS(layout); for(ngroup=bmain->nodetree.first, event=0; ngroup; ngroup= ngroup->id.next, ++event) { /* only use group trees */ if (ngroup->type==ntree->type && ELEM3(ngroup->nodetype, NODE_GROUP, NODE_FORLOOP, NODE_WHILELOOP)) { uiItemV(layout, ngroup->id.name+2, 0, event); } } } else if (nodeclass==NODE_DYNAMIC) { /* disabled */ } else { bNodeType *ntype; uiLayoutSetFunc(layout, do_node_add_static, NULL); for (ntype=ntreeGetType(ntree->type)->node_types.first; ntype; ntype=ntype->next) { if(ntype->nclass==nodeclass && ntype->name) uiItemV(layout, ntype->name, 0, ntype->type); } } }
static void node_menu_add(const bContext *C, Menu *menu) { Scene *scene = CTX_data_scene(C); SpaceNode *snode = CTX_wm_space_node(C); uiLayout *layout = menu->layout; bNodeTreeType *ntreetype = ntreeGetType(snode->treetype); if (!snode->nodetree) uiLayoutSetActive(layout, FALSE); uiLayoutSetOperatorContext(layout, WM_OP_INVOKE_DEFAULT); uiItemO(layout, "Search ...", 0, "NODE_OT_add_search"); if (ntreetype && ntreetype->foreach_nodeclass) ntreetype->foreach_nodeclass(scene, layout, node_menu_add_foreach_cb); }
static void ui_template_node_link_menu(bContext *C, uiLayout *layout, void *but_p) { Main *bmain= CTX_data_main(C); Scene *scene= CTX_data_scene(C); uiBlock *block = uiLayoutGetBlock(layout); uiBut *but = (uiBut*)but_p; uiLayout *split, *column; NodeLinkArg *arg = (NodeLinkArg*)but->func_argN; bNodeSocket *sock = arg->sock; bNodeTreeType *ntreetype= ntreeGetType(arg->ntree->type); uiBlockSetCurLayout(block, layout); split= uiLayoutSplit(layout, 0, 0); arg->bmain= bmain; arg->scene= scene; arg->layout= split; if (ntreetype && ntreetype->foreach_nodeclass) ntreetype->foreach_nodeclass(scene, arg, node_menu_column_foreach_cb); column= uiLayoutColumn(split, 0); uiBlockSetCurLayout(block, column); if (sock->link) { uiItemL(column, "Link", ICON_NONE); but= block->buttons.last; but->flag= UI_TEXT_LEFT; but = uiDefBut(block, BUT, 0, "Remove", 0, 0, UI_UNIT_X*4, UI_UNIT_Y, NULL, 0.0, 0.0, 0.0, 0.0, "Remove nodes connected to the input"); uiButSetNFunc(but, ui_node_link, MEM_dupallocN(arg), SET_INT_IN_POINTER(UI_NODE_LINK_REMOVE)); but = uiDefBut(block, BUT, 0, "Disconnect", 0, 0, UI_UNIT_X*4, UI_UNIT_Y, NULL, 0.0, 0.0, 0.0, 0.0, "Disconnect nodes connected to the input"); uiButSetNFunc(but, ui_node_link, MEM_dupallocN(arg), SET_INT_IN_POINTER(UI_NODE_LINK_DISCONNECT)); } ui_node_menu_column(arg, NODE_CLASS_GROUP, IFACE_("Group")); }
static void ui_node_menu_column(NodeLinkArg *arg, int nclass, const char *cname) { Main *bmain = arg->bmain; bNodeTree *ntree = arg->ntree; bNodeSocket *sock = arg->sock; uiLayout *layout = arg->layout; uiLayout *column = NULL; uiBlock *block = uiLayoutGetBlock(layout); uiBut *but; bNodeType *ntype; bNodeTree *ngroup; NodeLinkArg *argN; int first = 1; int compatibility= 0; if (ntree->type == NTREE_SHADER) { if (BKE_scene_use_new_shading_nodes(arg->scene)) compatibility= NODE_NEW_SHADING; else compatibility= NODE_OLD_SHADING; } if (nclass == NODE_CLASS_GROUP) { for (ngroup=bmain->nodetree.first; ngroup; ngroup=ngroup->id.next) { bNodeSocket *gsock; char name[UI_MAX_NAME_STR]; int i, j, num = 0; if (ngroup->type != ntree->type) continue; for (gsock=ngroup->inputs.first; gsock; gsock=gsock->next) if (ui_compatible_sockets(gsock->type, sock->type)) num++; for (i=0, j=0, gsock=ngroup->outputs.first; gsock; gsock=gsock->next, i++) { if (!ui_compatible_sockets(gsock->type, sock->type)) continue; if (first) { column= uiLayoutColumn(layout, 0); uiBlockSetCurLayout(block, column); uiItemL(column, cname, ICON_NODE); but= block->buttons.last; but->flag= UI_TEXT_LEFT; first = 0; } if (num > 1) { if (j == 0) { uiItemL(column, ngroup->id.name+2, ICON_NODE); but= block->buttons.last; but->flag= UI_TEXT_LEFT; } BLI_snprintf(name, UI_MAX_NAME_STR, " %s", gsock->name); j++; } else BLI_strncpy(name, ngroup->id.name+2, UI_MAX_NAME_STR); but = uiDefBut(block, BUT, 0, ngroup->id.name+2, 0, 0, UI_UNIT_X*4, UI_UNIT_Y, NULL, 0.0, 0.0, 0.0, 0.0, "Add node to input"); argN = MEM_dupallocN(arg); argN->type = NODE_GROUP; argN->ngroup = ngroup; argN->output = i; uiButSetNFunc(but, ui_node_link, argN, NULL); } } } else { bNodeTreeType *ttype= ntreeGetType(ntree->type); for (ntype=ttype->node_types.first; ntype; ntype=ntype->next) { bNodeSocketTemplate *stemp; char name[UI_MAX_NAME_STR]; int i, j, num = 0; if (compatibility && !(ntype->compatibility & compatibility)) continue; if (ntype->nclass != nclass) continue; for (i=0, stemp=ntype->outputs; stemp && stemp->type != -1; stemp++, i++) if (ui_compatible_sockets(stemp->type, sock->type)) num++; for (i=0, j=0, stemp=ntype->outputs; stemp && stemp->type != -1; stemp++, i++) { if (!ui_compatible_sockets(stemp->type, sock->type)) continue; if (first) { column= uiLayoutColumn(layout, 0); uiBlockSetCurLayout(block, column); uiItemL(column, cname, ICON_NODE); but= block->buttons.last; but->flag= UI_TEXT_LEFT; first = 0; } if (num > 1) { if (j == 0) { uiItemL(column, ntype->name, ICON_NODE); but= block->buttons.last; but->flag= UI_TEXT_LEFT; } BLI_snprintf(name, UI_MAX_NAME_STR, " %s", stemp->name); j++; } else BLI_strncpy(name, ntype->name, UI_MAX_NAME_STR); but = uiDefBut(block, BUT, 0, name, 0, 0, UI_UNIT_X*4, UI_UNIT_Y, NULL, 0.0, 0.0, 0.0, 0.0, "Add node to input"); argN = MEM_dupallocN(arg); argN->type = ntype->type; argN->output = i; uiButSetNFunc(but, ui_node_link, argN, NULL); } } } }