diff options
Diffstat (limited to 'source/blender/nodes/composite/nodes/node_composite_outputFile.c')
-rw-r--r-- | source/blender/nodes/composite/nodes/node_composite_outputFile.c | 251 |
1 files changed, 41 insertions, 210 deletions
diff --git a/source/blender/nodes/composite/nodes/node_composite_outputFile.c b/source/blender/nodes/composite/nodes/node_composite_outputFile.c index 214617c91e5..18bb97c70ed 100644 --- a/source/blender/nodes/composite/nodes/node_composite_outputFile.c +++ b/source/blender/nodes/composite/nodes/node_composite_outputFile.c @@ -31,8 +31,13 @@ #include <string.h> +#include "BLI_utildefines.h" #include "BLI_path_util.h" +#include "BKE_context.h" + +#include "RNA_access.h" + #include "node_composite_util.h" #include "IMB_imbuf.h" @@ -44,18 +49,18 @@ /* **************** OUTPUT FILE ******************** */ /* find unique path */ -static int unique_path_unique_check(void *arg, const char *name) +static bool unique_path_unique_check(void *arg, const char *name) { struct {ListBase *lb; bNodeSocket *sock;} *data= arg; bNodeSocket *sock; - for (sock=data->lb->first; sock; sock=sock->next) { + for (sock=data->lb->first; sock; sock = sock->next) { if (sock != data->sock) { NodeImageMultiFileSocket *sockdata = sock->storage; - if (strcmp(sockdata->path, name)==0) - return 1; + if (STREQ(sockdata->path, name)) + return true; } } - return 0; + return false; } void ntreeCompositOutputFileUniquePath(ListBase *list, bNodeSocket *sock, const char defname[], char delim) { @@ -73,18 +78,18 @@ void ntreeCompositOutputFileUniquePath(ListBase *list, bNodeSocket *sock, const } /* find unique EXR layer */ -static int unique_layer_unique_check(void *arg, const char *name) +static bool unique_layer_unique_check(void *arg, const char *name) { struct {ListBase *lb; bNodeSocket *sock;} *data= arg; bNodeSocket *sock; - for (sock=data->lb->first; sock; sock=sock->next) { + for (sock=data->lb->first; sock; sock = sock->next) { if (sock != data->sock) { NodeImageMultiFileSocket *sockdata = sock->storage; - if (strcmp(sockdata->layer, name)==0) - return 1; + if (STREQ(sockdata->layer, name)) + return true; } } - return 0; + return false; } void ntreeCompositOutputFileUniqueLayer(ListBase *list, bNodeSocket *sock, const char defname[], char delim) { @@ -104,7 +109,7 @@ void ntreeCompositOutputFileUniqueLayer(ListBase *list, bNodeSocket *sock, const bNodeSocket *ntreeCompositOutputFileAddSocket(bNodeTree *ntree, bNode *node, const char *name, ImageFormatData *im_format) { NodeImageMultiFile *nimf = node->storage; - bNodeSocket *sock = nodeAddSocket(ntree, node, SOCK_IN, "", SOCK_RGBA); + bNodeSocket *sock = nodeAddStaticSocket(ntree, node, SOCK_IN, SOCK_RGBA, PROP_NONE, NULL, name); /* create format data for the input socket */ NodeImageMultiFileSocket *sockdata = MEM_callocN(sizeof(NodeImageMultiFileSocket), "socket image format"); @@ -164,14 +169,19 @@ void ntreeCompositOutputFileSetLayer(bNode *node, bNodeSocket *sock, const char ntreeCompositOutputFileUniqueLayer(&node->inputs, sock, name, '_'); } -static void init_output_file(bNodeTree *ntree, bNode *node, bNodeTemplate *ntemp) +/* XXX uses initfunc_api callback, regular initfunc does not support context yet */ +static void init_output_file(const bContext *C, PointerRNA *ptr) { + Scene *scene = CTX_data_scene(C); + bNodeTree *ntree = ptr->id.data; + bNode *node = ptr->data; NodeImageMultiFile *nimf= MEM_callocN(sizeof(NodeImageMultiFile), "node image multi file"); ImageFormatData *format = NULL; node->storage= nimf; + + if (scene) { + RenderData *rd = &scene->r; - if (ntemp->scene) { - RenderData *rd = &ntemp->scene->r; BLI_strncpy(nimf->base_path, rd->pic, sizeof(nimf->base_path)); nimf->format = rd->im_format; if (BKE_imtype_is_movie(nimf->format.imtype)) { @@ -192,229 +202,50 @@ static void free_output_file(bNode *node) bNodeSocket *sock; /* free storage data in sockets */ - for (sock=node->inputs.first; sock; sock=sock->next) { + for (sock = node->inputs.first; sock; sock = sock->next) { MEM_freeN(sock->storage); } MEM_freeN(node->storage); } -static void copy_output_file(struct bNode *node, struct bNode *target) +static void copy_output_file(bNodeTree *UNUSED(dest_ntree), bNode *dest_node, bNode *src_node) { - bNodeSocket *sock, *newsock; + bNodeSocket *src_sock, *dest_sock; - target->storage = MEM_dupallocN(node->storage); + dest_node->storage = MEM_dupallocN(src_node->storage); /* duplicate storage data in sockets */ - for (sock=node->inputs.first, newsock=target->inputs.first; sock && newsock; sock=sock->next, newsock=newsock->next) { - newsock->storage = MEM_dupallocN(sock->storage); + for (src_sock=src_node->inputs.first, dest_sock=dest_node->inputs.first; src_sock && dest_sock; src_sock=src_sock->next, dest_sock=dest_sock->next) { + dest_sock->storage = MEM_dupallocN(src_sock->storage); } } -static void update_output_file(bNodeTree *UNUSED(ntree), bNode *node) +static void update_output_file(bNodeTree *ntree, bNode *node) { bNodeSocket *sock; + PointerRNA ptr; + + cmp_node_update_default(ntree, node); /* automatically update the socket type based on linked input */ - for (sock=node->inputs.first; sock; sock=sock->next) { + for (sock = node->inputs.first; sock; sock = sock->next) { if (sock->link) { - int linktype = sock->link->fromsock->type; - if (linktype != sock->type) - nodeSocketSetType(sock, linktype); - } - } -} - -#ifdef WITH_COMPOSITOR_LEGACY - -/* write input data into individual files */ -static void exec_output_file_singlelayer(RenderData *rd, bNode *node, bNodeStack **in) -{ - Main *bmain= G.main; /* TODO, have this passed along */ - NodeImageMultiFile *nimf= node->storage; - bNodeSocket *sock; - int i; - int has_preview = 0; - - for (sock=node->inputs.first, i=0; sock; sock=sock->next, ++i) { - if (in[i]->data) { - NodeImageMultiFileSocket *sockdata = sock->storage; - ImageFormatData *format = (sockdata->use_node_format ? &nimf->format : &sockdata->format); - char path[FILE_MAX]; - char filename[FILE_MAX]; - CompBuf *cbuf = NULL; - ImBuf *ibuf; - - switch (format->planes) { - case R_IMF_PLANES_BW: - cbuf = typecheck_compbuf(in[i]->data, CB_VAL); - break; - case R_IMF_PLANES_RGB: - cbuf = typecheck_compbuf(in[i]->data, CB_VEC3); - break; - case R_IMF_PLANES_RGBA: - cbuf = typecheck_compbuf(in[i]->data, CB_RGBA); - break; - } - - ibuf = IMB_allocImBuf(cbuf->x, cbuf->y, format->planes, 0); - /* XXX have to set this explicitly it seems */ - switch (format->planes) { - case R_IMF_PLANES_BW: ibuf->channels = 1; break; - case R_IMF_PLANES_RGB: ibuf->channels = 3; break; - case R_IMF_PLANES_RGBA: ibuf->channels = 4; break; - } - ibuf->rect_float = cbuf->rect; - ibuf->dither = rd->dither_intensity; - - /* get full path */ - 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_imbuf_write(ibuf, filename, format)) - printf("Cannot save Node File Output to %s\n", filename); - else - printf("Saved: %s\n", filename); - - IMB_freeImBuf(ibuf); - - /* simply pick the first valid input for preview */ - if (!has_preview) { - generate_preview(rd, node, cbuf); - has_preview = 1; - } - - if (in[i]->data != cbuf) - free_compbuf(cbuf); - } - } -} - -/* write input data into layers */ -static void exec_output_file_multilayer(RenderData *rd, bNode *node, bNodeStack **in) -{ - Main *bmain= G.main; /* TODO, have this passed along */ - NodeImageMultiFile *nimf= node->storage; - void *exrhandle= IMB_exr_get_handle(); - char filename[FILE_MAX]; - bNodeSocket *sock; - int i; - /* Must have consistent pixel size for exr file, simply take the first valid input size. */ - int rectx = -1; - int recty = -1; - int has_preview = 0; - - BKE_makepicstring(filename, nimf->base_path, bmain->name, rd->cfra, R_IMF_IMTYPE_MULTILAYER, (rd->scemode & R_EXTENSION), TRUE); - BLI_make_existing_file(filename); - - 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 channelname[EXR_TOT_MAXNAME]; /* '.' and single character channel name is appended */ - char *channelname_ext; - - if (cbuf->rect_procedural) { - printf("Error writing multilayer EXR: Procedural buffer not supported\n"); - continue; - } - if (rectx < 0) { - rectx = cbuf->x; - recty = cbuf->y; - } - else if (cbuf->x != rectx || cbuf->y != recty) { - printf("Error: Multilayer EXR output node %s expects same resolution for all input buffers. Layer %s skipped.\n", node->name, sock->name); - continue; - } - - BLI_strncpy(channelname, sockdata->layer, sizeof(channelname)-2); - channelname_ext = channelname + strlen(channelname); - - /* create channels */ - switch (cbuf->type) { - case CB_VAL: - strcpy(channelname_ext, ".V"); - IMB_exr_add_channel(exrhandle, NULL, channelname, 1, rectx, cbuf->rect); - break; - case CB_VEC2: - strcpy(channelname_ext, ".X"); - IMB_exr_add_channel(exrhandle, NULL, channelname, 2, 2*rectx, cbuf->rect); - strcpy(channelname_ext, ".Y"); - IMB_exr_add_channel(exrhandle, NULL, channelname, 2, 2*rectx, cbuf->rect+1); - break; - case CB_VEC3: - strcpy(channelname_ext, ".X"); - IMB_exr_add_channel(exrhandle, NULL, channelname, 3, 3*rectx, cbuf->rect); - strcpy(channelname_ext, ".Y"); - IMB_exr_add_channel(exrhandle, NULL, channelname, 3, 3*rectx, cbuf->rect+1); - strcpy(channelname_ext, ".Z"); - IMB_exr_add_channel(exrhandle, NULL, channelname, 3, 3*rectx, cbuf->rect+2); - break; - case CB_RGBA: - strcpy(channelname_ext, ".R"); - IMB_exr_add_channel(exrhandle, NULL, channelname, 4, 4*rectx, cbuf->rect); - strcpy(channelname_ext, ".G"); - IMB_exr_add_channel(exrhandle, NULL, channelname, 4, 4*rectx, cbuf->rect+1); - strcpy(channelname_ext, ".B"); - IMB_exr_add_channel(exrhandle, NULL, channelname, 4, 4*rectx, cbuf->rect+2); - strcpy(channelname_ext, ".A"); - IMB_exr_add_channel(exrhandle, NULL, channelname, 4, 4*rectx, cbuf->rect+3); - break; - } - - /* simply pick the first valid input for preview */ - if (!has_preview) { - generate_preview(rd, node, cbuf); - has_preview = 1; - } + RNA_pointer_create((ID *)ntree, &RNA_NodeSocket, sock, &ptr); + RNA_enum_set(&ptr, "type", sock->link->fromsock->type); } } - - /* when the filename has no permissions, this can fail */ - if (IMB_exr_begin_write(exrhandle, filename, rectx, recty, nimf->format.exr_codec)) { - IMB_exr_write_channels(exrhandle); - } - else { - /* TODO, get the error from openexr's exception */ - /* XXX nice way to do report? */ - printf("Error Writing Render Result, see console\n"); - } - - IMB_exr_close(exrhandle); -} - -static void node_composit_exec_outputfile(void *data, bNode *node, bNodeStack **in, bNodeStack **UNUSED(out)) -{ - RenderData *rd= data; - NodeImageMultiFile *nimf= node->storage; - - if (G.is_rendering == FALSE) { - /* only output files when rendering a sequence - - * otherwise, it overwrites the output files just - * scrubbing through the timeline when the compositor updates */ - return; - } - - if (nimf->format.imtype==R_IMF_IMTYPE_MULTILAYER) - exec_output_file_multilayer(rd, node, in); - else - exec_output_file_singlelayer(rd, node, in); } -#endif /* WITH_COMPOSITOR_LEGACY */ -void register_node_type_cmp_output_file(bNodeTreeType *ttype) +void register_node_type_cmp_output_file(void) { static bNodeType ntype; - node_type_base(ttype, &ntype, CMP_NODE_OUTPUT_FILE, "File Output", NODE_CLASS_OUTPUT, NODE_OPTIONS|NODE_PREVIEW); + cmp_node_type_base(&ntype, CMP_NODE_OUTPUT_FILE, "File Output", NODE_CLASS_OUTPUT, NODE_OPTIONS|NODE_PREVIEW); node_type_socket_templates(&ntype, NULL, NULL); - node_type_size(&ntype, 140, 80, 300); - node_type_init(&ntype, init_output_file); + ntype.initfunc_api = init_output_file; node_type_storage(&ntype, "NodeImageMultiFile", free_output_file, copy_output_file); node_type_update(&ntype, update_output_file, NULL); -#ifdef WITH_COMPOSITOR_LEGACY - node_type_exec(&ntype, node_composit_exec_outputfile); -#endif - nodeRegisterType(ttype, &ntype); + nodeRegisterType(&ntype); } |