Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source/blender/blenkernel/BKE_node.h3
-rw-r--r--source/blender/blenloader/intern/readfile.c38
-rw-r--r--source/blender/editors/space_node/drawnode.c248
-rw-r--r--source/blender/editors/space_node/node_buttons.c6
-rw-r--r--source/blender/editors/space_node/node_draw.c26
-rw-r--r--source/blender/editors/space_node/node_edit.c84
-rw-r--r--source/blender/editors/space_node/node_intern.h1
-rw-r--r--source/blender/editors/space_node/node_ops.c1
-rw-r--r--source/blender/makesdna/DNA_node_types.h9
-rw-r--r--source/blender/makesrna/intern/rna_nodetree.c83
-rw-r--r--source/blender/nodes/composite/nodes/node_composite_outputFile.c12
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 */