2 * ***** BEGIN GPL LICENSE BLOCK *****
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version 2
7 * of the License, or (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software Foundation,
16 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18 * The Original Code is Copyright (C) 2006 Blender Foundation.
19 * All rights reserved.
21 * The Original Code is: all of this file.
23 * Contributor(s): none yet.
25 * ***** END GPL LICENSE BLOCK *****
28 /** \file blender/nodes/composite/nodes/node_composite_outputFile.c
34 #include "BLI_path_util.h"
36 #include "BKE_utildefines.h"
38 #include "node_composite_util.h"
40 /* **************** OUTPUT FILE ******************** */
41 static bNodeSocketTemplate cmp_node_output_file_in[]= {
42 { SOCK_RGBA, 1, "Image", 0.0f, 0.0f, 0.0f, 1.0f},
43 { SOCK_FLOAT, 1, "Z", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, PROP_NONE},
47 static void node_composit_exec_output_file(void *data, bNode *node, bNodeStack **in, bNodeStack **UNUSED(out))
49 /* image assigned to output */
50 /* stack order input sockets: col, alpha */
54 NodeImageFile *nif= node->storage;
55 if(nif->sfra!=nif->efra && (rd->cfra<nif->sfra || rd->cfra>nif->efra)) {
56 return; /* BAIL OUT RETURN */
58 else if (!G.rendering) {
59 /* only output files when rendering a sequence -
60 * otherwise, it overwrites the output files just
61 * scrubbing through the timeline when the compositor updates */
64 Main *bmain= G.main; /* TODO, have this passed along */
65 CompBuf *cbuf= typecheck_compbuf(in[0]->data, CB_RGBA);
66 ImBuf *ibuf= IMB_allocImBuf(cbuf->x, cbuf->y, 32, 0);
67 char string[FILE_MAX];
69 ibuf->rect_float= cbuf->rect;
70 ibuf->dither= rd->dither_intensity;
72 if (rd->color_mgt_flag & R_COLOR_MANAGEMENT)
73 ibuf->profile = IB_PROFILE_LINEAR_RGB;
76 CompBuf *zbuf= in[1]->data;
77 if(zbuf->type==CB_VAL && zbuf->x==cbuf->x && zbuf->y==cbuf->y) {
78 nif->im_format.flag |= R_IMF_FLAG_ZBUF;
79 ibuf->zbuf_float= zbuf->rect;
83 BKE_makepicstring(string, nif->name, bmain->name, rd->cfra, nif->im_format.imtype, (rd->scemode & R_EXTENSION), TRUE);
85 if(0 == BKE_write_ibuf(ibuf, string, &nif->im_format))
86 printf("Cannot save Node File Output to %s\n", string);
88 printf("Saved: %s\n", string);
92 generate_preview(data, node, cbuf);
94 if(in[0]->data != cbuf)
100 static void node_composit_mute_output_file(void *UNUSED(data), int UNUSED(thread),
101 struct bNode *UNUSED(node), void *UNUSED(nodedata),
102 struct bNodeStack **UNUSED(in), struct bNodeStack **UNUSED(out))
104 /* nothing to do here */
107 static void node_composit_init_output_file(bNodeTree *UNUSED(ntree), bNode* node, bNodeTemplate *ntemp)
109 RenderData *rd = &ntemp->scene->r;
110 NodeImageFile *nif= MEM_callocN(sizeof(NodeImageFile), "node image file");
113 BLI_strncpy(nif->name, rd->pic, sizeof(nif->name));
114 nif->im_format= rd->im_format;
115 if (BKE_imtype_is_movie(nif->im_format.imtype)) {
116 nif->im_format.imtype= R_IMF_IMTYPE_OPENEXR;
122 void register_node_type_cmp_output_file(bNodeTreeType *ttype)
124 static bNodeType ntype;
126 node_type_base(ttype, &ntype, CMP_NODE_OUTPUT_FILE, "File Output", NODE_CLASS_OUTPUT, NODE_PREVIEW|NODE_OPTIONS);
127 node_type_socket_templates(&ntype, cmp_node_output_file_in, NULL);
128 node_type_size(&ntype, 140, 80, 300);
129 node_type_init(&ntype, node_composit_init_output_file);
130 node_type_storage(&ntype, "NodeImageFile", node_free_standard_storage, node_copy_standard_storage);
131 node_type_exec(&ntype, node_composit_exec_output_file);
132 node_type_mute(&ntype, node_composit_mute_output_file, NULL);
134 nodeRegisterType(ttype, &ntype);
138 /* =============================================================================== */
141 void ntreeCompositOutputMultiFileAddSocket(bNodeTree *ntree, bNode *node, ImageFormatData *im_format)
143 bNodeSocket *sock = nodeAddSocket(ntree, node, SOCK_IN, "", SOCK_RGBA);
145 /* create format data for the input socket */
146 NodeImageMultiFileSocket *sockdata = MEM_callocN(sizeof(NodeImageMultiFileSocket), "socket image format");
147 sock->storage = sockdata;
148 sock->struct_type = SOCK_STRUCT_OUTPUT_MULTI_FILE;
151 sockdata->format= *im_format;
152 if (BKE_imtype_is_movie(sockdata->format.imtype)) {
153 sockdata->format.imtype= R_IMF_IMTYPE_OPENEXR;
156 /* use render data format by default */
157 sockdata->use_render_format = 1;
160 int ntreeCompositOutputMultiFileRemoveActiveSocket(bNodeTree *ntree, bNode *node)
162 NodeImageMultiFile *nimf = node->storage;
163 bNodeSocket *sock = BLI_findlink(&node->inputs, nimf->active_input);
168 /* free format data */
169 MEM_freeN(sock->storage);
171 nodeRemoveSocket(ntree, node, sock);
175 static void init_output_multi_file(bNodeTree *ntree, bNode* node, bNodeTemplate *ntemp)
177 RenderData *rd = &ntemp->scene->r;
178 NodeImageMultiFile *nimf= MEM_callocN(sizeof(NodeImageMultiFile), "node image multi file");
181 BLI_strncpy(nimf->base_path, rd->pic, sizeof(nimf->base_path));
183 /* add one socket by default */
184 ntreeCompositOutputMultiFileAddSocket(ntree, node, &rd->im_format);
187 void free_output_multi_file(bNode *node)
191 /* free storage data in sockets */
192 for (sock=node->inputs.first; sock; sock=sock->next) {
193 MEM_freeN(sock->storage);
196 MEM_freeN(node->storage);
199 void copy_output_multi_file(struct bNode *node, struct bNode *target)
201 bNodeSocket *sock, *newsock;
203 target->storage = MEM_dupallocN(node->storage);
205 /* duplicate storage data in sockets */
206 for (sock=node->inputs.first, newsock=target->inputs.first; sock && newsock; sock=sock->next, newsock=newsock->next) {
207 newsock->storage = MEM_dupallocN(sock->storage);
211 static void exec_output_multi_file(void *data, bNode *node, bNodeStack **in, bNodeStack **UNUSED(out))
213 RenderData *rd= data;
214 NodeImageMultiFile *nimf= node->storage;
218 for (sock=node->inputs.first, i=0; sock; sock=sock->next, ++i) {
223 /* only output files when rendering a sequence -
224 * otherwise, it overwrites the output files just
225 * scrubbing through the timeline when the compositor updates */
228 Main *bmain= G.main; /* TODO, have this passed along */
229 NodeImageMultiFileSocket *sockdata = sock->storage;
230 CompBuf *cbuf= typecheck_compbuf(in[i]->data, CB_RGBA);
231 ImBuf *ibuf= IMB_allocImBuf(cbuf->x, cbuf->y, 32, 0);
232 ImageFormatData *format = (sockdata->use_render_format ? &rd->im_format : &sockdata->format);
234 char string[FILE_MAX];
236 ibuf->rect_float= cbuf->rect;
237 ibuf->dither= rd->dither_intensity;
239 if (rd->color_mgt_flag & R_COLOR_MANAGEMENT)
240 ibuf->profile = IB_PROFILE_LINEAR_RGB;
243 BLI_join_dirfile(path, FILE_MAX, nimf->base_path, sock->name);
245 BKE_makepicstring(string, path, bmain->name, rd->cfra, format->imtype, (rd->scemode & R_EXTENSION), TRUE);
247 if(0 == BKE_write_ibuf(ibuf, string, format))
248 printf("Cannot save Node File Output to %s\n", string);
250 printf("Saved: %s\n", string);
254 #if 0 /* XXX not used yet */
255 generate_preview(data, node, cbuf);
258 if(in[i]->data != cbuf)
264 static void mute_output_multi_file(void *UNUSED(data), int UNUSED(thread),
265 struct bNode *UNUSED(node), void *UNUSED(nodedata),
266 struct bNodeStack **UNUSED(in), struct bNodeStack **UNUSED(out))
268 /* nothing to do here */
271 void register_node_type_cmp_output_multi_file(bNodeTreeType *ttype)
273 static bNodeType ntype;
275 node_type_base(ttype, &ntype, CMP_NODE_OUTPUT_MULTI_FILE, "Multi File Output", NODE_CLASS_OUTPUT, NODE_OPTIONS);
276 node_type_socket_templates(&ntype, NULL, NULL);
277 node_type_size(&ntype, 140, 80, 300);
278 node_type_init(&ntype, init_output_multi_file);
279 node_type_storage(&ntype, "NodeImageMultiFile", free_output_multi_file, copy_output_multi_file);
280 node_type_exec(&ntype, exec_output_multi_file);
281 node_type_mute(&ntype, mute_output_multi_file, NULL);
283 nodeRegisterType(ttype, &ntype);