diff options
-rw-r--r-- | source/blender/blenkernel/BKE_node.h | 3 | ||||
-rw-r--r-- | source/blender/blenloader/intern/readfile.c | 38 | ||||
-rw-r--r-- | source/blender/editors/space_node/drawnode.c | 248 | ||||
-rw-r--r-- | source/blender/editors/space_node/node_buttons.c | 6 | ||||
-rw-r--r-- | source/blender/editors/space_node/node_draw.c | 26 | ||||
-rw-r--r-- | source/blender/editors/space_node/node_edit.c | 84 | ||||
-rw-r--r-- | source/blender/editors/space_node/node_intern.h | 1 | ||||
-rw-r--r-- | source/blender/editors/space_node/node_ops.c | 1 | ||||
-rw-r--r-- | source/blender/makesdna/DNA_node_types.h | 9 | ||||
-rw-r--r-- | source/blender/makesrna/intern/rna_nodetree.c | 83 | ||||
-rw-r--r-- | source/blender/nodes/composite/nodes/node_composite_outputFile.c | 12 |
11 files changed, 308 insertions, 203 deletions
diff --git a/source/blender/blenkernel/BKE_node.h b/source/blender/blenkernel/BKE_node.h index a4eddd0b590..e7e1577c6b4 100644 --- a/source/blender/blenkernel/BKE_node.h +++ b/source/blender/blenkernel/BKE_node.h @@ -145,6 +145,9 @@ typedef struct bNodeType { void (*uifunc)(struct uiLayout *, struct bContext *C, struct PointerRNA *ptr); /// Additional parameters in the side panel. void (*uifuncbut)(struct uiLayout *, struct bContext *C, struct PointerRNA *ptr); + /// Draw a node socket. Default draws the input value button. + NodeSocketButtonFunction drawinputfunc; + NodeSocketButtonFunction drawoutputfunc; /// Optional custom label function for the node header. const char *(*labelfunc)(struct bNode *); /// Optional custom resize handle polling. diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index 5dd0a1b996f..1813bd49936 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -7786,6 +7786,23 @@ static void do_versions_mesh_mloopcol_swap_2_62_1(Mesh *me) } } +static void do_versions_nodetree_multi_file_output_path_2_64_0(bNodeTree *ntree) +{ + bNode *node; + + for (node=ntree->nodes.first; node; node=node->next) { + if (node->type==CMP_NODE_OUTPUT_FILE) { + bNodeSocket *sock; + for (sock=node->inputs.first; sock; sock=sock->next) { + NodeImageMultiFileSocket *input = sock->storage; + /* input file path is stored in dedicated struct now instead socket name */ + BLI_strncpy(input->path, sock->name, sizeof(input->path)); + sock->name[0] = '\0'; /* unused */ + } + } + } +} + static void do_versions(FileData *fd, Library *lib, Main *main) { /* WATCH IT!!!: pointers from libdata have not been converted */ @@ -13282,10 +13299,23 @@ static void do_versions(FileData *fd, Library *lib, Main *main) if (main->versionfile < 263) { - /* Default for old files is to save particle rotations to pointcache */ - ParticleSettings *part; - for (part = main->particle.first; part; part = part->id.next) - part->flag |= PART_ROTATIONS; + { + /* Default for old files is to save particle rotations to pointcache */ + ParticleSettings *part; + for (part = main->particle.first; part; part = part->id.next) + part->flag |= PART_ROTATIONS; + } + { + /* file output node paths are now stored in the file info struct instead socket name */ + Scene *sce; + bNodeTree *ntree; + + for (sce = main->scene.first; sce; sce=sce->id.next) + if (sce->nodetree) + do_versions_nodetree_multi_file_output_path_2_64_0(sce->nodetree); + for (ntree = main->nodetree.first; ntree; ntree=ntree->id.next) + do_versions_nodetree_multi_file_output_path_2_64_0(ntree); + } } if (main->versionfile <= 263 && main->subversionfile == 0) { diff --git a/source/blender/editors/space_node/drawnode.c b/source/blender/editors/space_node/drawnode.c index f8ed6c20657..69e5cbefde5 100644 --- a/source/blender/editors/space_node/drawnode.c +++ b/source/blender/editors/space_node/drawnode.c @@ -98,71 +98,23 @@ static void node_socket_button_label(const bContext *UNUSED(C), uiBlock *block, uiDefBut(block, LABEL, 0, sock->name, x, y, width, NODE_DY, NULL, 0, 0, 0, 0, ""); } -/* draw function for file output node sockets. - * XXX a bit ugly use atm, called from datatype button functions, - * since all node types and callbacks only use data type without struct_type. - */ -static void node_socket_button_output_file(const bContext *C, uiBlock *block, - bNodeTree *ntree, bNode *node, bNodeSocket *sock, - const char *UNUSED(name), int x, int y, int width) -{ - uiLayout *layout, *row; - PointerRNA nodeptr, sockptr, imfptr; - int imtype; - int rx, ry; - RNA_pointer_create(&ntree->id, &RNA_Node, node, &nodeptr); - RNA_pointer_create(&ntree->id, &RNA_NodeSocket, sock, &sockptr); - - layout = uiBlockLayout(block, UI_LAYOUT_VERTICAL, UI_LAYOUT_PANEL, x, y+NODE_DY, width, 20, UI_GetStyle()); - row = uiLayoutRow(layout, 0); - - uiItemL(row, sock->name, 0); - - imfptr = RNA_pointer_get(&nodeptr, "format"); - imtype = RNA_enum_get(&imfptr, "file_format"); - /* in multilayer format all socket format details are ignored */ - if (imtype != R_IMF_IMTYPE_MULTILAYER) { - PropertyRNA *imtype_prop; - const char *imtype_name; - - if (!RNA_boolean_get(&sockptr, "use_node_format")) - imfptr = RNA_pointer_get(&sockptr, "format"); - - imtype_prop = RNA_struct_find_property(&imfptr, "file_format"); - RNA_property_enum_name((bContext*)C, &imfptr, imtype_prop, RNA_property_enum_get(&imfptr, imtype_prop), &imtype_name); - uiBlockSetEmboss(block, UI_EMBOSSP); - uiItemL(row, imtype_name, 0); - uiBlockSetEmboss(block, UI_EMBOSSN); - } - - uiBlockLayoutResolve(block, &rx, &ry); -} - static void node_socket_button_default(const bContext *C, uiBlock *block, bNodeTree *ntree, bNode *node, bNodeSocket *sock, const char *name, int x, int y, int width) { - switch (sock->struct_type) { - case SOCK_STRUCT_NONE: { - if (sock->link || (sock->flag & SOCK_HIDE_VALUE)) - node_socket_button_label(C, block, ntree, node, sock, name, x, y, width); - else { - PointerRNA ptr; - uiBut *bt; - - RNA_pointer_create(&ntree->id, &RNA_NodeSocket, sock, &ptr); - - bt = uiDefButR(block, NUM, B_NODE_EXEC, name, - x, y+1, width, NODE_DY-2, - &ptr, "default_value", 0, 0, 0, -1, -1, NULL); - if (node) - uiButSetFunc(bt, node_sync_cb, CTX_wm_space_node(C), node); - } - break; - } - case SOCK_STRUCT_OUTPUT_FILE: - node_socket_button_output_file(C, block, ntree, node, sock, name, x, y, width); - break; + if (sock->link || (sock->flag & SOCK_HIDE_VALUE)) + node_socket_button_label(C, block, ntree, node, sock, name, x, y, width); + else { + PointerRNA ptr; + uiBut *bt; + + RNA_pointer_create(&ntree->id, &RNA_NodeSocket, sock, &ptr); + + bt = uiDefButR(block, NUM, B_NODE_EXEC, name, + x, y+1, width, NODE_DY-2, + &ptr, "default_value", 0, 0, 0, -1, -1, NULL); + if (node) + uiButSetFunc(bt, node_sync_cb, CTX_wm_space_node(C), node); } } @@ -192,33 +144,25 @@ static void node_socket_button_components(const bContext *C, uiBlock *block, bNodeTree *ntree, bNode *node, bNodeSocket *sock, const char *name, int x, int y, int width) { - switch (sock->struct_type) { - case SOCK_STRUCT_NONE: { - if (sock->link || (sock->flag & SOCK_HIDE_VALUE)) - node_socket_button_label(C, block, ntree, node, sock, name, x, y, width); - else { - PointerRNA ptr; - SocketComponentMenuArgs *args; - - RNA_pointer_create(&ntree->id, &RNA_NodeSocket, sock, &ptr); - - args= MEM_callocN(sizeof(SocketComponentMenuArgs), "SocketComponentMenuArgs"); - - args->ptr = ptr; - args->x = x; - args->y = y; - args->width = width; - args->cb = node_sync_cb; - args->arg1 = CTX_wm_space_node(C); - args->arg2 = node; - - uiDefBlockButN(block, socket_component_menu, args, name, x, y+1, width, NODE_DY-2, ""); - } - break; - } - case SOCK_STRUCT_OUTPUT_FILE: - node_socket_button_output_file(C, block, ntree, node, sock, name, x, y, width); - break; + if (sock->link || (sock->flag & SOCK_HIDE_VALUE)) + node_socket_button_label(C, block, ntree, node, sock, name, x, y, width); + else { + PointerRNA ptr; + SocketComponentMenuArgs *args; + + RNA_pointer_create(&ntree->id, &RNA_NodeSocket, sock, &ptr); + + args= MEM_callocN(sizeof(SocketComponentMenuArgs), "SocketComponentMenuArgs"); + + args->ptr = ptr; + args->x = x; + args->y = y; + args->width = width; + args->cb = node_sync_cb; + args->arg1 = CTX_wm_space_node(C); + args->arg2 = node; + + uiDefBlockButN(block, socket_component_menu, args, name, x, y+1, width, NODE_DY-2, ""); } } @@ -226,35 +170,52 @@ static void node_socket_button_color(const bContext *C, uiBlock *block, bNodeTree *ntree, bNode *node, bNodeSocket *sock, const char *name, int x, int y, int width) { - /* XXX would be nicer to have draw function based on sock->struct_type as well, - * but currently socket types are completely identified by data type only. - */ - - switch (sock->struct_type) { - case SOCK_STRUCT_NONE: { - if (sock->link || (sock->flag & SOCK_HIDE_VALUE)) - node_socket_button_label(C, block, ntree, node, sock, name, x, y, width); - else { - PointerRNA ptr; - uiBut *bt; - int labelw= width - 40; - RNA_pointer_create(&ntree->id, &RNA_NodeSocket, sock, &ptr); - - bt=uiDefButR(block, COL, B_NODE_EXEC, "", - x, y+2, (labelw>0 ? 40 : width), NODE_DY-2, - &ptr, "default_value", 0, 0, 0, -1, -1, NULL); - if (node) - uiButSetFunc(bt, node_sync_cb, CTX_wm_space_node(C), node); - - if (name[0]!='\0' && labelw>0) - uiDefBut(block, LABEL, 0, name, x + 40, y+2, labelw, NODE_DY-2, NULL, 0, 0, 0, 0, ""); - } - break; + if (sock->link || (sock->flag & SOCK_HIDE_VALUE)) + node_socket_button_label(C, block, ntree, node, sock, name, x, y, width); + else { + PointerRNA ptr; + uiBut *bt; + int labelw= width - 40; + RNA_pointer_create(&ntree->id, &RNA_NodeSocket, sock, &ptr); + + bt=uiDefButR(block, COL, B_NODE_EXEC, "", + x, y+2, (labelw>0 ? 40 : width), NODE_DY-2, + &ptr, "default_value", 0, 0, 0, -1, -1, NULL); + if (node) + uiButSetFunc(bt, node_sync_cb, CTX_wm_space_node(C), node); + + if (name[0]!='\0' && labelw>0) + uiDefBut(block, LABEL, 0, name, x + 40, y+2, labelw, NODE_DY-2, NULL, 0, 0, 0, 0, ""); } - case SOCK_STRUCT_OUTPUT_FILE: - node_socket_button_output_file(C, block, ntree, node, sock, name, x, y, width); - break; +} + +/* standard draw function, display the default input value */ +static void node_draw_input_default(const bContext *C, uiBlock *block, + bNodeTree *ntree, bNode *node, bNodeSocket *sock, + const char *name, int x, int y, int width) +{ + bNodeSocketType *stype = ntreeGetSocketType(sock->type); + if (stype->buttonfunc) + stype->buttonfunc(C, block, ntree, node, sock, name, x, y, width); + else + node_socket_button_label(C, block, ntree, node, sock, name, x, y, width); +} + +static void node_draw_output_default(const bContext *C, uiBlock *block, + bNodeTree *UNUSED(ntree), bNode *node, bNodeSocket *sock, + const char *name, int UNUSED(x), int UNUSED(y), int UNUSED(width)) +{ + SpaceNode *snode = CTX_wm_space_node(C); + float slen; + int ofs = 0; + UI_ThemeColor(TH_TEXT); + slen= snode->aspect*UI_GetStringWidth(name); + while (slen > node->width) { + ofs++; + slen= snode->aspect*UI_GetStringWidth(name+ofs); } + uiDefBut(block, LABEL, 0, name+ofs, (short)(sock->locx-15.0f-slen), (short)(sock->locy-9.0f), + (short)(node->width-NODE_DY), NODE_DY, NULL, 0, 0, 0, 0, ""); } /* ****************** BASE DRAW FUNCTIONS FOR NEW OPERATOR NODES ***************** */ @@ -1743,6 +1704,43 @@ static void node_composit_buts_id_mask(uiLayout *layout, bContext *UNUSED(C), Po uiItemR(layout, ptr, "use_smooth_mask", 0, NULL, ICON_NONE); } +/* draw function for file output node sockets, displays only sub-path and format, no value button */ +static void node_draw_input_file_output(const bContext *C, uiBlock *block, + bNodeTree *ntree, bNode *node, bNodeSocket *sock, + const char *UNUSED(name), int x, int y, int width) +{ + NodeImageMultiFileSocket *input = sock->storage; + uiLayout *layout, *row; + PointerRNA nodeptr, inputptr, imfptr; + int imtype; + int rx, ry; + RNA_pointer_create(&ntree->id, &RNA_Node, node, &nodeptr); + RNA_pointer_create(&ntree->id, &RNA_NodeImageFileSocket, input, &inputptr); + + layout = uiBlockLayout(block, UI_LAYOUT_VERTICAL, UI_LAYOUT_PANEL, x, y+NODE_DY, width, 20, UI_GetStyle()); + row = uiLayoutRow(layout, 0); + + uiItemL(row, input->path, 0); + + imfptr = RNA_pointer_get(&nodeptr, "format"); + imtype = RNA_enum_get(&imfptr, "file_format"); + /* in multilayer format all socket format details are ignored */ + if (imtype != R_IMF_IMTYPE_MULTILAYER) { + PropertyRNA *imtype_prop; + const char *imtype_name; + + if (!RNA_boolean_get(&inputptr, "use_node_format")) + imfptr = RNA_pointer_get(&inputptr, "format"); + + imtype_prop = RNA_struct_find_property(&imfptr, "file_format"); + RNA_property_enum_name((bContext*)C, &imfptr, imtype_prop, RNA_property_enum_get(&imfptr, imtype_prop), &imtype_name); + uiBlockSetEmboss(block, UI_EMBOSSP); + uiItemL(row, imtype_name, 0); + uiBlockSetEmboss(block, UI_EMBOSSN); + } + + uiBlockLayoutResolve(block, &rx, &ry); +} static void node_composit_buts_file_output(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr) { PointerRNA imfptr = RNA_pointer_get(ptr, "format"); @@ -1757,7 +1755,9 @@ static void node_composit_buts_file_output(uiLayout *layout, bContext *UNUSED(C) static void node_composit_buts_file_output_details(uiLayout *layout, bContext *C, PointerRNA *ptr) { PointerRNA imfptr = RNA_pointer_get(ptr, "format"); - PointerRNA active_input_ptr = RNA_pointer_get(ptr, "active_input"); + PointerRNA active_input_ptr, op_ptr; + uiLayout *col, *row; + int active_index; int multilayer = (RNA_enum_get(&imfptr, "file_format") == R_IMF_IMTYPE_MULTILAYER); node_composit_buts_file_output(layout, C, ptr); @@ -1767,7 +1767,16 @@ static void node_composit_buts_file_output_details(uiLayout *layout, bContext *C uiItemO(layout, "Add Input", ICON_ZOOMIN, "NODE_OT_output_file_add_socket"); - uiTemplateList(layout, C, ptr, "inputs", ptr, "active_input_index", NULL, 0, 0, 0); + uiTemplateList(layout, C, ptr, "file_inputs", ptr, "active_input_index", NULL, 0, 0, 0); + + active_index = RNA_int_get(ptr, "active_input_index"); + RNA_property_collection_lookup_int(ptr, RNA_struct_find_property(ptr, "file_inputs"), active_index, &active_input_ptr); + + row = uiLayoutRow(layout, 1); + op_ptr = uiItemFullO(row, "NODE_OT_output_file_move_active_socket", "", ICON_TRIA_UP, NULL, WM_OP_INVOKE_DEFAULT, UI_ITEM_O_RETURN_PROPS); + RNA_enum_set(&op_ptr, "direction", 1); + op_ptr = uiItemFullO(row, "NODE_OT_output_file_move_active_socket", "", ICON_TRIA_DOWN, NULL, WM_OP_INVOKE_DEFAULT, UI_ITEM_O_RETURN_PROPS); + RNA_enum_set(&op_ptr, "direction", 2); if (active_input_ptr.data) { uiLayout *row, *col; @@ -1778,7 +1787,7 @@ static void node_composit_buts_file_output_details(uiLayout *layout, bContext *C else uiItemL(col, "File Path:", 0); row = uiLayoutRow(col, 0); - uiItemR(row, &active_input_ptr, "name", 0, "", 0); + uiItemR(row, &active_input_ptr, "path", 0, "", 0); uiItemFullO(row, "NODE_OT_output_file_remove_active_socket", "", ICON_X, NULL, WM_OP_EXEC_DEFAULT, UI_ITEM_R_ICON_ONLY); /* in multilayer format all socket format details are ignored */ @@ -2033,6 +2042,7 @@ static void node_composit_set_butfunc(bNodeType *ntype) case CMP_NODE_OUTPUT_FILE: ntype->uifunc= node_composit_buts_file_output; ntype->uifuncbut= node_composit_buts_file_output_details; + ntype->drawinputfunc = node_draw_input_file_output; break; case CMP_NODE_DIFF_MATTE: ntype->uifunc=node_composit_buts_diff_matte; @@ -2292,6 +2302,8 @@ void ED_init_node_butfuncs(void) ntype->drawupdatefunc = node_update_default; ntype->uifunc = NULL; ntype->uifuncbut = NULL; + ntype->drawinputfunc = node_draw_input_default; + ntype->drawoutputfunc = node_draw_output_default; ntype->resize_area_func = node_resize_area_default; node_common_set_butfunc(ntype); diff --git a/source/blender/editors/space_node/node_buttons.c b/source/blender/editors/space_node/node_buttons.c index f7d517915da..c92abf116c4 100644 --- a/source/blender/editors/space_node/node_buttons.c +++ b/source/blender/editors/space_node/node_buttons.c @@ -89,7 +89,7 @@ static void active_node_panel(const bContext *C, Panel *pa) SpaceNode *snode= CTX_wm_space_node(C); bNodeTree *ntree= (snode) ? snode->edittree : NULL; bNode *node = (ntree) ? nodeGetActive(ntree) : NULL; // xxx... for editing group nodes - uiLayout *layout= pa->layout; + uiLayout *layout; PointerRNA ptr; /* verify pointers, and create RNA pointer for the node */ @@ -100,6 +100,10 @@ static void active_node_panel(const bContext *C, Panel *pa) //else RNA_pointer_create(&ntree->id, &RNA_Node, node, &ptr); + /* XXX nicer way to make sub-layout? */ + layout = uiLayoutColumn(pa->layout, 0); + uiLayoutSetContextPointer(layout, "node", &ptr); + /* draw this node's name, etc. */ uiItemR(layout, &ptr, "label", 0, NULL, ICON_NODE); uiItemS(layout); diff --git a/source/blender/editors/space_node/node_draw.c b/source/blender/editors/space_node/node_draw.c index 7cddaa5e0e7..3a920e16f8a 100644 --- a/source/blender/editors/space_node/node_draw.c +++ b/source/blender/editors/space_node/node_draw.c @@ -303,6 +303,7 @@ static void node_update_basis(const bContext *C, bNodeTree *ntree, bNode *node) layout= uiBlockLayout(node->block, UI_LAYOUT_VERTICAL, UI_LAYOUT_PANEL, locx+NODE_DYS, dy, node->butr.xmax, NODE_DY, UI_GetStyle()); + uiLayoutSetContextPointer(layout, "node", &ptr); node->typeinfo->uifunc(layout, (bContext *)C, &ptr); @@ -711,41 +712,24 @@ static void node_draw_basis(const bContext *C, ARegion *ar, SpaceNode *snode, bN /* socket inputs, buttons */ for (sock= node->inputs.first; sock; sock= sock->next) { - bNodeSocketType *stype= ntreeGetSocketType(sock->type); - if (nodeSocketIsHidden(sock)) continue; node_socket_circle_draw(ntree, sock, NODE_SOCKSIZE); - if (stype->buttonfunc) - stype->buttonfunc(C, node->block, ntree, node, sock, IFACE_(sock->name), sock->locx+NODE_DYS, sock->locy-NODE_DYS, node->width-NODE_DY); + node->typeinfo->drawinputfunc(C, node->block, ntree, node, sock, IFACE_(sock->name), + sock->locx+NODE_DYS, sock->locy-NODE_DYS, node->width-NODE_DY); } /* socket outputs */ for (sock= node->outputs.first; sock; sock= sock->next) { - PointerRNA sockptr; - - RNA_pointer_create((ID*)ntree, &RNA_NodeSocket, sock, &sockptr); - if (nodeSocketIsHidden(sock)) continue; node_socket_circle_draw(ntree, sock, NODE_SOCKSIZE); - { - const char *name = IFACE_(sock->name); - float slen; - int ofs = 0; - UI_ThemeColor(TH_TEXT); - slen= snode->aspect*UI_GetStringWidth(name); - while (slen > node->width) { - ofs++; - slen= snode->aspect*UI_GetStringWidth(name+ofs); - } - uiDefBut(node->block, LABEL, 0, name+ofs, (short)(sock->locx-15.0f-slen), (short)(sock->locy-9.0f), - (short)(node->width-NODE_DY), NODE_DY, NULL, 0, 0, 0, 0, ""); - } + node->typeinfo->drawoutputfunc(C, node->block, ntree, node, sock, IFACE_(sock->name), + sock->locx-node->width+NODE_DYS, sock->locy-NODE_DYS, node->width-NODE_DY); } /* preview */ diff --git a/source/blender/editors/space_node/node_edit.c b/source/blender/editors/space_node/node_edit.c index b63770ef049..c0817f9c895 100644 --- a/source/blender/editors/space_node/node_edit.c +++ b/source/blender/editors/space_node/node_edit.c @@ -3591,12 +3591,16 @@ static int node_output_file_add_socket_exec(bContext *C, wmOperator *op) { Scene *scene= CTX_data_scene(C); SpaceNode *snode= CTX_wm_space_node(C); - bNodeTree *ntree = snode->edittree; - bNode *node = nodeGetActive(ntree); + PointerRNA ptr; + bNodeTree *ntree; + bNode *node; char file_path[MAX_NAME]; - if (!node) + ptr = CTX_data_pointer_get(C, "node"); + if (!ptr.data) return OPERATOR_CANCELLED; + node = ptr.data; + ntree = ptr.id.data; RNA_string_get(op->ptr, "file_path", file_path); ntreeCompositOutputFileAddSocket(ntree, node, file_path, &scene->r.im_format); @@ -3628,11 +3632,14 @@ void NODE_OT_output_file_add_socket(wmOperatorType *ot) static int node_output_file_remove_active_socket_exec(bContext *C, wmOperator *UNUSED(op)) { SpaceNode *snode= CTX_wm_space_node(C); - bNodeTree *ntree = snode->edittree; - bNode *node = nodeGetActive(ntree); + PointerRNA ptr = CTX_data_pointer_get(C, "node"); + bNodeTree *ntree; + bNode *node; - if (!node) + if (!ptr.data) return OPERATOR_CANCELLED; + node = ptr.data; + ntree = ptr.id.data; if (!ntreeCompositOutputFileRemoveActiveSocket(ntree, node)) return OPERATOR_CANCELLED; @@ -3656,3 +3663,68 @@ void NODE_OT_output_file_remove_active_socket(wmOperatorType *ot) /* flags */ ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO; } + +/* ****************** Multi File Output Move Socket ******************* */ + +static int node_output_file_move_active_socket_exec(bContext *C, wmOperator *op) +{ + SpaceNode *snode= CTX_wm_space_node(C); + PointerRNA ptr = CTX_data_pointer_get(C, "node"); + bNode *node; + NodeImageMultiFile *nimf; + bNodeSocket *sock; + int direction; + + if (!ptr.data) + return OPERATOR_CANCELLED; + node = ptr.data; + nimf = node->storage; + + sock = BLI_findlink(&node->inputs, nimf->active_input); + if (!sock) + return OPERATOR_CANCELLED; + + direction = RNA_enum_get(op->ptr, "direction"); + + if (direction==1) { + bNodeSocket *before = sock->prev; + if (!before) + return OPERATOR_CANCELLED; + BLI_remlink(&node->inputs, sock); + BLI_insertlinkbefore(&node->inputs, before, sock); + --nimf->active_input; + } + else { + bNodeSocket *after = sock->next; + if (!after) + return OPERATOR_CANCELLED; + BLI_remlink(&node->inputs, sock); + BLI_insertlinkafter(&node->inputs, after, sock); + ++nimf->active_input; + } + + snode_notify(C, snode); + + return OPERATOR_FINISHED; +} + +void NODE_OT_output_file_move_active_socket(wmOperatorType *ot) +{ + static EnumPropertyItem direction_items[] = { + {1, "UP", 0, "Up", ""}, + {2, "DOWN", 0, "Down", ""}}; + + /* identifiers */ + ot->name = "Move File Node Socket"; + ot->description = "Move the active input of a file output node up or down the list"; + ot->idname = "NODE_OT_output_file_move_active_socket"; + + /* callbacks */ + ot->exec = node_output_file_move_active_socket_exec; + ot->poll = composite_node_active; + + /* flags */ + ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO; + + RNA_def_enum(ot->srna, "direction", direction_items, 2, "Direction", ""); +} diff --git a/source/blender/editors/space_node/node_intern.h b/source/blender/editors/space_node/node_intern.h index aa80f729343..17078443987 100644 --- a/source/blender/editors/space_node/node_intern.h +++ b/source/blender/editors/space_node/node_intern.h @@ -166,6 +166,7 @@ void NODE_OT_new_node_tree(struct wmOperatorType *ot); void NODE_OT_output_file_add_socket(struct wmOperatorType *ot); void NODE_OT_output_file_remove_active_socket(struct wmOperatorType *ot); +void NODE_OT_output_file_move_active_socket(struct wmOperatorType *ot); extern const char *node_context_dir[]; diff --git a/source/blender/editors/space_node/node_ops.c b/source/blender/editors/space_node/node_ops.c index 25940787b60..1c681220016 100644 --- a/source/blender/editors/space_node/node_ops.c +++ b/source/blender/editors/space_node/node_ops.c @@ -103,6 +103,7 @@ void node_operatortypes(void) WM_operatortype_append(NODE_OT_output_file_add_socket); WM_operatortype_append(NODE_OT_output_file_remove_active_socket); + WM_operatortype_append(NODE_OT_output_file_move_active_socket); } void ED_operatormacros_node(void) diff --git a/source/blender/makesdna/DNA_node_types.h b/source/blender/makesdna/DNA_node_types.h index 01096b6459e..6874e8de4f1 100644 --- a/source/blender/makesdna/DNA_node_types.h +++ b/source/blender/makesdna/DNA_node_types.h @@ -77,7 +77,7 @@ typedef struct bNodeSocket { short type, flag; short limit; /* max. number of links */ - short struct_type; /* optional identifier for RNA struct subtype */ + short pad1; float locx, locy; @@ -87,7 +87,7 @@ typedef struct bNodeSocket { short stack_index; /* local stack index */ /* XXX deprecated, kept for forward compatibility */ short stack_type DNA_DEPRECATED; - int pad3; + int pad2; void *cache; /* cached data from execution */ /* internal data to retrieve relations and groups */ @@ -112,10 +112,6 @@ typedef struct bNodeSocket { #define SOCK_INT 6 #define NUM_SOCKET_TYPES 7 /* must be last! */ -/* sock->struct_type */ -#define SOCK_STRUCT_NONE 0 /* default, type is defined by sock->type only */ -#define SOCK_STRUCT_OUTPUT_FILE 1 /* file output node socket */ - /* socket side (input/output) */ #define SOCK_IN 1 #define SOCK_OUT 2 @@ -371,6 +367,7 @@ typedef struct NodeImageMultiFileSocket { short use_render_format DNA_DEPRECATED; short use_node_format; /* use overall node image format */ int pad2; + char path[1024]; /* 1024 = FILE_MAX */ ImageFormatData format; } NodeImageMultiFileSocket; diff --git a/source/blender/makesrna/intern/rna_nodetree.c b/source/blender/makesrna/intern/rna_nodetree.c index 5173d927e83..cffcca177b3 100644 --- a/source/blender/makesrna/intern/rna_nodetree.c +++ b/source/blender/makesrna/intern/rna_nodetree.c @@ -245,28 +245,22 @@ static StructRNA *rna_NodeSocket_refine(PointerRNA *ptr) return &RNA_NodeSocket##stypename##idname; \ } - switch (sock->struct_type) { - case SOCK_STRUCT_NONE: - switch (sock->type) { - case SOCK_FLOAT: - NODE_DEFINE_SUBTYPES_FLOAT - break; - case SOCK_INT: - NODE_DEFINE_SUBTYPES_INT - break; - case SOCK_BOOLEAN: - return &RNA_NodeSocketBoolean; - case SOCK_VECTOR: - NODE_DEFINE_SUBTYPES_VECTOR - break; - case SOCK_RGBA: - return &RNA_NodeSocketRGBA; - case SOCK_SHADER: - return &RNA_NodeSocketShader; - } - break; - case SOCK_STRUCT_OUTPUT_FILE: - return &RNA_NodeImageFileSocket; + switch (sock->type) { + case SOCK_FLOAT: + NODE_DEFINE_SUBTYPES_FLOAT + break; + case SOCK_INT: + NODE_DEFINE_SUBTYPES_INT + break; + case SOCK_BOOLEAN: + return &RNA_NodeSocketBoolean; + case SOCK_VECTOR: + NODE_DEFINE_SUBTYPES_VECTOR + break; + case SOCK_RGBA: + return &RNA_NodeSocketRGBA; + case SOCK_SHADER: + return &RNA_NodeSocketShader; } #undef SUBTYPE @@ -858,14 +852,18 @@ static void rna_Mapping_Node_update(Main *bmain, Scene *scene, PointerRNA *ptr) rna_Node_update(bmain, scene, ptr); } -static PointerRNA rna_CompositNodeOutputMultiFile_active_input_get(PointerRNA *ptr) +static void rna_NodeOutputFile_file_inputs_begin(CollectionPropertyIterator *iter, PointerRNA *ptr) { bNode *node = ptr->data; - NodeImageMultiFile *nimf = node->storage; - bNodeSocket *sock = BLI_findlink(&node->inputs, nimf->active_input); - PointerRNA sock_ptr; - RNA_pointer_create((ID*)ptr->id.data, &RNA_NodeSocket, sock, &sock_ptr); - return sock_ptr; + rna_iterator_listbase_begin(iter, &node->inputs, NULL); +} + +static PointerRNA rna_NodeOutputFile_file_inputs_get(CollectionPropertyIterator *iter) +{ + PointerRNA ptr; + bNodeSocket *sock = rna_iterator_listbase_get(iter); + RNA_pointer_create(iter->ptr.id.data, &RNA_NodeImageFileSocket, sock->storage, &ptr); + return ptr; } #else @@ -1827,22 +1825,23 @@ static void rna_def_cmp_output_file_socket(BlenderRNA *brna) StructRNA *srna; PropertyRNA *prop; - srna = RNA_def_struct(brna, "NodeImageFileSocket", "NodeSocketRGBA"); - RNA_def_struct_sdna(srna, "bNodeSocket"); - RNA_def_struct_path_func(srna, "rna_NodeSocket_path"); + srna = RNA_def_struct(brna, "NodeImageFileSocket", NULL); + RNA_def_struct_sdna(srna, "NodeImageMultiFileSocket"); RNA_def_struct_ui_text(srna, "Node Image File Socket", "Socket data of file output node"); - RNA_def_struct_ui_icon(srna, ICON_PLUG); - RNA_def_struct_sdna_from(srna, "bNodeSocket", NULL); - - RNA_def_struct_sdna_from(srna, "NodeImageMultiFileSocket", "storage"); prop = RNA_def_property(srna, "use_node_format", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "use_node_format", 1); RNA_def_property_ui_text(prop, "Use Node Format", ""); - RNA_def_property_update(prop, NC_NODE|NA_EDITED, "rna_NodeSocket_update"); + RNA_def_property_update(prop, NC_NODE|NA_EDITED, NULL); prop = RNA_def_property(srna, "format", PROP_POINTER, PROP_NONE); RNA_def_property_struct_type(prop, "ImageFormatSettings"); + + prop = RNA_def_property(srna, "path", PROP_STRING, PROP_FILEPATH); + RNA_def_property_string_sdna(prop, NULL, "path"); + RNA_def_property_ui_text(prop, "Path", "Subpath used for this input"); + RNA_def_struct_name_property(srna, prop); + RNA_def_property_update(prop, NC_NODE|NA_EDITED, NULL); } static void def_cmp_output_file(StructRNA *srna) { @@ -1855,12 +1854,6 @@ static void def_cmp_output_file(StructRNA *srna) RNA_def_property_ui_text(prop, "Base Path", "Base output path for the image"); RNA_def_property_update(prop, NC_NODE|NA_EDITED, "rna_Node_update"); - prop = RNA_def_property(srna, "active_input", PROP_POINTER, PROP_NONE); - RNA_def_property_pointer_funcs(prop, "rna_CompositNodeOutputMultiFile_active_input_get", NULL, NULL, NULL); - RNA_def_property_struct_type(prop, "NodeSocket"); - RNA_def_property_clear_flag(prop, PROP_EDITABLE); - RNA_def_property_ui_text(prop, "Active Input", "Active input in details view list"); - prop = RNA_def_property(srna, "active_input_index", PROP_INT, PROP_NONE); RNA_def_property_int_sdna(prop, NULL, "active_input"); RNA_def_property_ui_text(prop, "Active Input Index", "Active input index in details view list"); @@ -1868,6 +1861,12 @@ static void def_cmp_output_file(StructRNA *srna) prop = RNA_def_property(srna, "format", PROP_POINTER, PROP_NONE); RNA_def_property_struct_type(prop, "ImageFormatSettings"); + + prop = RNA_def_property(srna, "file_inputs", PROP_COLLECTION, PROP_NONE); + RNA_def_property_collection_funcs(prop, "rna_NodeOutputFile_file_inputs_begin", "rna_iterator_listbase_next", "rna_iterator_listbase_end", + "rna_NodeOutputFile_file_inputs_get", NULL, NULL, NULL, NULL); + RNA_def_property_struct_type(prop, "NodeImageFileSocket"); + RNA_def_property_ui_text(prop, "File Inputs", ""); } static void def_cmp_dilate_erode(StructRNA *srna) diff --git a/source/blender/nodes/composite/nodes/node_composite_outputFile.c b/source/blender/nodes/composite/nodes/node_composite_outputFile.c index 2eb68c787fb..f89dcf63f64 100644 --- a/source/blender/nodes/composite/nodes/node_composite_outputFile.c +++ b/source/blender/nodes/composite/nodes/node_composite_outputFile.c @@ -48,12 +48,13 @@ bNodeSocket *ntreeCompositOutputFileAddSocket(bNodeTree *ntree, bNode *node, const char *name, ImageFormatData *im_format) { NodeImageMultiFile *nimf = node->storage; - bNodeSocket *sock = nodeAddSocket(ntree, node, SOCK_IN, name, SOCK_RGBA); + bNodeSocket *sock = nodeAddSocket(ntree, node, SOCK_IN, "", SOCK_RGBA); /* create format data for the input socket */ NodeImageMultiFileSocket *sockdata = MEM_callocN(sizeof(NodeImageMultiFileSocket), "socket image format"); sock->storage = sockdata; - sock->struct_type = SOCK_STRUCT_OUTPUT_FILE; + + BLI_strncpy(sockdata->path, name, sizeof(sockdata->path)); if (im_format) { sockdata->format= *im_format; @@ -188,7 +189,7 @@ static void exec_output_file_singlelayer(RenderData *rd, bNode *node, bNodeStack ibuf->profile = IB_PROFILE_LINEAR_RGB; /* get full path */ - BLI_join_dirfile(path, FILE_MAX, nimf->base_path, sock->name); + BLI_join_dirfile(path, FILE_MAX, nimf->base_path, sockdata->path); BKE_makepicstring(filename, path, bmain->name, rd->cfra, format->imtype, (rd->scemode & R_EXTENSION), TRUE); if (0 == BKE_write_ibuf(ibuf, filename, format)) @@ -229,6 +230,7 @@ static void exec_output_file_multilayer(RenderData *rd, bNode *node, bNodeStack for (sock=node->inputs.first, i=0; sock; sock=sock->next, ++i) { if (in[i]->data) { + NodeImageMultiFileSocket *sockdata = sock->storage; CompBuf *cbuf = in[i]->data; char layname[EXR_LAY_MAXNAME]; char channelname[EXR_PASS_MAXNAME]; @@ -247,8 +249,8 @@ static void exec_output_file_multilayer(RenderData *rd, bNode *node, bNodeStack continue; } - BLI_strncpy(layname, sock->name, sizeof(layname)); - BLI_strncpy(channelname, sock->name, sizeof(channelname)-2); + BLI_strncpy(layname, sockdata->path, sizeof(layname)); + BLI_strncpy(channelname, sockdata->path, sizeof(channelname)-2); channelname_ext = channelname + strlen(channelname); /* create channels */ |