117
118
if (passtype == SCE_PASS_COMBINED) {
118
if (channel==-1) return "Combined";
119
if (channel==0) return "Combined.R";
120
if (channel==1) return "Combined.G";
121
if (channel==2) return "Combined.B";
119
if (channel == -1) return "Combined";
120
if (channel == 0) return "Combined.R";
121
if (channel == 1) return "Combined.G";
122
if (channel == 2) return "Combined.B";
122
123
return "Combined.A";
124
125
if (passtype == SCE_PASS_Z) {
125
if (channel==-1) return "Depth";
126
if (channel == -1) return "Depth";
126
127
return "Depth.Z";
128
129
if (passtype == SCE_PASS_VECTOR) {
129
if (channel==-1) return "Vector";
130
if (channel==0) return "Vector.X";
131
if (channel==1) return "Vector.Y";
132
if (channel==2) return "Vector.Z";
130
if (channel == -1) return "Vector";
131
if (channel == 0) return "Vector.X";
132
if (channel == 1) return "Vector.Y";
133
if (channel == 2) return "Vector.Z";
133
134
return "Vector.W";
135
136
if (passtype == SCE_PASS_NORMAL) {
136
if (channel==-1) return "Normal";
137
if (channel==0) return "Normal.X";
138
if (channel==1) return "Normal.Y";
137
if (channel == -1) return "Normal";
138
if (channel == 0) return "Normal.X";
139
if (channel == 1) return "Normal.Y";
139
140
return "Normal.Z";
141
142
if (passtype == SCE_PASS_UV) {
142
if (channel==-1) return "UV";
143
if (channel==0) return "UV.U";
144
if (channel==1) return "UV.V";
143
if (channel == -1) return "UV";
144
if (channel == 0) return "UV.U";
145
if (channel == 1) return "UV.V";
147
148
if (passtype == SCE_PASS_RGBA) {
148
if (channel==-1) return "Color";
149
if (channel==0) return "Color.R";
150
if (channel==1) return "Color.G";
151
if (channel==2) return "Color.B";
149
if (channel == -1) return "Color";
150
if (channel == 0) return "Color.R";
151
if (channel == 1) return "Color.G";
152
if (channel == 2) return "Color.B";
152
153
return "Color.A";
154
155
if (passtype == SCE_PASS_EMIT) {
155
if (channel==-1) return "Emit";
156
if (channel==0) return "Emit.R";
157
if (channel==1) return "Emit.G";
156
if (channel == -1) return "Emit";
157
if (channel == 0) return "Emit.R";
158
if (channel == 1) return "Emit.G";
160
161
if (passtype == SCE_PASS_DIFFUSE) {
161
if (channel==-1) return "Diffuse";
162
if (channel==0) return "Diffuse.R";
163
if (channel==1) return "Diffuse.G";
162
if (channel == -1) return "Diffuse";
163
if (channel == 0) return "Diffuse.R";
164
if (channel == 1) return "Diffuse.G";
164
165
return "Diffuse.B";
166
167
if (passtype == SCE_PASS_SPEC) {
167
if (channel==-1) return "Spec";
168
if (channel==0) return "Spec.R";
169
if (channel==1) return "Spec.G";
168
if (channel == -1) return "Spec";
169
if (channel == 0) return "Spec.R";
170
if (channel == 1) return "Spec.G";
172
173
if (passtype == SCE_PASS_SHADOW) {
173
if (channel==-1) return "Shadow";
174
if (channel==0) return "Shadow.R";
175
if (channel==1) return "Shadow.G";
174
if (channel == -1) return "Shadow";
175
if (channel == 0) return "Shadow.R";
176
if (channel == 1) return "Shadow.G";
176
177
return "Shadow.B";
178
179
if (passtype == SCE_PASS_AO) {
179
if (channel==-1) return "AO";
180
if (channel==0) return "AO.R";
181
if (channel==1) return "AO.G";
180
if (channel == -1) return "AO";
181
if (channel == 0) return "AO.R";
182
if (channel == 1) return "AO.G";
184
185
if (passtype == SCE_PASS_ENVIRONMENT) {
185
if (channel==-1) return "Env";
186
if (channel==0) return "Env.R";
187
if (channel==1) return "Env.G";
186
if (channel == -1) return "Env";
187
if (channel == 0) return "Env.R";
188
if (channel == 1) return "Env.G";
190
191
if (passtype == SCE_PASS_INDIRECT) {
191
if (channel==-1) return "Indirect";
192
if (channel==0) return "Indirect.R";
193
if (channel==1) return "Indirect.G";
192
if (channel == -1) return "Indirect";
193
if (channel == 0) return "Indirect.R";
194
if (channel == 1) return "Indirect.G";
194
195
return "Indirect.B";
196
197
if (passtype == SCE_PASS_REFLECT) {
197
if (channel==-1) return "Reflect";
198
if (channel==0) return "Reflect.R";
199
if (channel==1) return "Reflect.G";
198
if (channel == -1) return "Reflect";
199
if (channel == 0) return "Reflect.R";
200
if (channel == 1) return "Reflect.G";
200
201
return "Reflect.B";
202
203
if (passtype == SCE_PASS_REFRACT) {
203
if (channel==-1) return "Refract";
204
if (channel==0) return "Refract.R";
205
if (channel==1) return "Refract.G";
204
if (channel == -1) return "Refract";
205
if (channel == 0) return "Refract.R";
206
if (channel == 1) return "Refract.G";
206
207
return "Refract.B";
208
209
if (passtype == SCE_PASS_INDEXOB) {
209
if (channel==-1) return "IndexOB";
210
if (channel == -1) return "IndexOB";
210
211
return "IndexOB.X";
212
213
if (passtype == SCE_PASS_INDEXMA) {
213
if (channel==-1) return "IndexMA";
214
if (channel == -1) return "IndexMA";
214
215
return "IndexMA.X";
216
217
if (passtype == SCE_PASS_MIST) {
217
if (channel==-1) return "Mist";
218
if (channel == -1) return "Mist";
220
221
if (passtype == SCE_PASS_RAYHITS) {
221
if (channel==-1) return "Rayhits";
222
if (channel==0) return "Rayhits.R";
223
if (channel==1) return "Rayhits.G";
222
if (channel == -1) return "Rayhits";
223
if (channel == 0) return "Rayhits.R";
224
if (channel == 1) return "Rayhits.G";
224
225
return "Rayhits.B";
226
227
if (passtype == SCE_PASS_DIFFUSE_DIRECT) {
227
if (channel==-1) return "DiffDir";
228
if (channel==0) return "DiffDir.R";
229
if (channel==1) return "DiffDir.G";
228
if (channel == -1) return "DiffDir";
229
if (channel == 0) return "DiffDir.R";
230
if (channel == 1) return "DiffDir.G";
230
231
return "DiffDir.B";
232
233
if (passtype == SCE_PASS_DIFFUSE_INDIRECT) {
233
if (channel==-1) return "DiffInd";
234
if (channel==0) return "DiffInd.R";
235
if (channel==1) return "DiffInd.G";
234
if (channel == -1) return "DiffInd";
235
if (channel == 0) return "DiffInd.R";
236
if (channel == 1) return "DiffInd.G";
236
237
return "DiffInd.B";
238
239
if (passtype == SCE_PASS_DIFFUSE_COLOR) {
239
if (channel==-1) return "DiffCol";
240
if (channel==0) return "DiffCol.R";
241
if (channel==1) return "DiffCol.G";
240
if (channel == -1) return "DiffCol";
241
if (channel == 0) return "DiffCol.R";
242
if (channel == 1) return "DiffCol.G";
242
243
return "DiffCol.B";
244
245
if (passtype == SCE_PASS_GLOSSY_DIRECT) {
245
if (channel==-1) return "GlossDir";
246
if (channel==0) return "GlossDir.R";
247
if (channel==1) return "GlossDir.G";
246
if (channel == -1) return "GlossDir";
247
if (channel == 0) return "GlossDir.R";
248
if (channel == 1) return "GlossDir.G";
248
249
return "GlossDir.B";
250
251
if (passtype == SCE_PASS_GLOSSY_INDIRECT) {
251
if (channel==-1) return "GlossInd";
252
if (channel==0) return "GlossInd.R";
253
if (channel==1) return "GlossInd.G";
252
if (channel == -1) return "GlossInd";
253
if (channel == 0) return "GlossInd.R";
254
if (channel == 1) return "GlossInd.G";
254
255
return "GlossInd.B";
256
257
if (passtype == SCE_PASS_GLOSSY_COLOR) {
257
if (channel==-1) return "GlossCol";
258
if (channel==0) return "GlossCol.R";
259
if (channel==1) return "GlossCol.G";
258
if (channel == -1) return "GlossCol";
259
if (channel == 0) return "GlossCol.R";
260
if (channel == 1) return "GlossCol.G";
260
261
return "GlossCol.B";
262
263
if (passtype == SCE_PASS_TRANSM_DIRECT) {
263
if (channel==-1) return "TransDir";
264
if (channel==0) return "TransDir.R";
265
if (channel==1) return "TransDir.G";
264
if (channel == -1) return "TransDir";
265
if (channel == 0) return "TransDir.R";
266
if (channel == 1) return "TransDir.G";
266
267
return "TransDir.B";
268
269
if (passtype == SCE_PASS_TRANSM_INDIRECT) {
269
if (channel==-1) return "TransInd";
270
if (channel==0) return "TransInd.R";
271
if (channel==1) return "TransInd.G";
270
if (channel == -1) return "TransInd";
271
if (channel == 0) return "TransInd.R";
272
if (channel == 1) return "TransInd.G";
272
273
return "TransInd.B";
274
275
if (passtype == SCE_PASS_TRANSM_COLOR) {
275
if (channel==-1) return "TransCol";
276
if (channel==0) return "TransCol.R";
277
if (channel==1) return "TransCol.G";
276
if (channel == -1) return "TransCol";
277
if (channel == 0) return "TransCol.R";
278
if (channel == 1) return "TransCol.G";
278
279
return "TransCol.B";
280
281
return "Unknown";
283
284
static int passtype_from_name(const char *str)
286
if (strcmp(str, "Combined")==0)
287
if (strcmp(str, "Combined") == 0)
287
288
return SCE_PASS_COMBINED;
289
if (strcmp(str, "Depth")==0)
290
if (strcmp(str, "Depth") == 0)
290
291
return SCE_PASS_Z;
292
if (strcmp(str, "Vector")==0)
293
if (strcmp(str, "Vector") == 0)
293
294
return SCE_PASS_VECTOR;
295
if (strcmp(str, "Normal")==0)
296
if (strcmp(str, "Normal") == 0)
296
297
return SCE_PASS_NORMAL;
298
if (strcmp(str, "UV")==0)
299
if (strcmp(str, "UV") == 0)
299
300
return SCE_PASS_UV;
301
if (strcmp(str, "Color")==0)
302
if (strcmp(str, "Color") == 0)
302
303
return SCE_PASS_RGBA;
304
if (strcmp(str, "Emit")==0)
305
if (strcmp(str, "Emit") == 0)
305
306
return SCE_PASS_EMIT;
307
if (strcmp(str, "Diffuse")==0)
308
if (strcmp(str, "Diffuse") == 0)
308
309
return SCE_PASS_DIFFUSE;
310
if (strcmp(str, "Spec")==0)
311
if (strcmp(str, "Spec") == 0)
311
312
return SCE_PASS_SPEC;
313
if (strcmp(str, "Shadow")==0)
314
if (strcmp(str, "Shadow") == 0)
314
315
return SCE_PASS_SHADOW;
316
if (strcmp(str, "AO")==0)
317
if (strcmp(str, "AO") == 0)
317
318
return SCE_PASS_AO;
319
if (strcmp(str, "Env")==0)
320
if (strcmp(str, "Env") == 0)
320
321
return SCE_PASS_ENVIRONMENT;
322
if (strcmp(str, "Indirect")==0)
323
if (strcmp(str, "Indirect") == 0)
323
324
return SCE_PASS_INDIRECT;
325
if (strcmp(str, "Reflect")==0)
326
if (strcmp(str, "Reflect") == 0)
326
327
return SCE_PASS_REFLECT;
328
if (strcmp(str, "Refract")==0)
329
if (strcmp(str, "Refract") == 0)
329
330
return SCE_PASS_REFRACT;
331
if (strcmp(str, "IndexOB")==0)
332
if (strcmp(str, "IndexOB") == 0)
332
333
return SCE_PASS_INDEXOB;
334
if (strcmp(str, "IndexMA")==0)
335
if (strcmp(str, "IndexMA") == 0)
335
336
return SCE_PASS_INDEXMA;
337
if (strcmp(str, "Mist")==0)
338
if (strcmp(str, "Mist") == 0)
338
339
return SCE_PASS_MIST;
340
if (strcmp(str, "RayHits")==0)
341
if (strcmp(str, "RayHits") == 0)
341
342
return SCE_PASS_RAYHITS;
343
if (strcmp(str, "DiffDir")==0)
344
if (strcmp(str, "DiffDir") == 0)
344
345
return SCE_PASS_DIFFUSE_DIRECT;
346
if (strcmp(str, "DiffInd")==0)
347
if (strcmp(str, "DiffInd") == 0)
347
348
return SCE_PASS_DIFFUSE_INDIRECT;
349
if (strcmp(str, "DiffCol")==0)
350
if (strcmp(str, "DiffCol") == 0)
350
351
return SCE_PASS_DIFFUSE_COLOR;
352
if (strcmp(str, "GlossDir")==0)
353
if (strcmp(str, "GlossDir") == 0)
353
354
return SCE_PASS_GLOSSY_DIRECT;
355
if (strcmp(str, "GlossInd")==0)
356
if (strcmp(str, "GlossInd") == 0)
356
357
return SCE_PASS_GLOSSY_INDIRECT;
358
if (strcmp(str, "GlossCol")==0)
359
if (strcmp(str, "GlossCol") == 0)
359
360
return SCE_PASS_GLOSSY_COLOR;
361
if (strcmp(str, "TransDir")==0)
362
if (strcmp(str, "TransDir") == 0)
362
363
return SCE_PASS_TRANSM_DIRECT;
364
if (strcmp(str, "TransInd")==0)
365
if (strcmp(str, "TransInd") == 0)
365
366
return SCE_PASS_TRANSM_INDIRECT;
367
if (strcmp(str, "TransCol")==0)
368
if (strcmp(str, "TransCol") == 0)
368
369
return SCE_PASS_TRANSM_COLOR;
375
376
static void render_layer_add_pass(RenderResult *rr, RenderLayer *rl, int channels, int passtype)
377
const char *typestr= get_pass_name(passtype, 0);
378
RenderPass *rpass= MEM_callocN(sizeof(RenderPass), typestr);
379
int rectsize= rr->rectx*rr->recty*channels;
378
const char *typestr = get_pass_name(passtype, 0);
379
RenderPass *rpass = MEM_callocN(sizeof(RenderPass), typestr);
380
int rectsize = rr->rectx * rr->recty * channels;
381
382
BLI_addtail(&rl->passes, rpass);
382
rpass->passtype= passtype;
383
rpass->channels= channels;
384
rpass->rectx= rl->rectx;
385
rpass->recty= rl->recty;
383
rpass->passtype = passtype;
384
rpass->channels = channels;
385
rpass->rectx = rl->rectx;
386
rpass->recty = rl->recty;
386
387
BLI_strncpy(rpass->name, get_pass_name(rpass->passtype, -1), sizeof(rpass->name));
390
for (a=0; a<channels; a++)
391
IMB_exr_add_channel(rr->exrhandle, rl->name, get_pass_name(passtype, a), 0, 0, NULL);
391
for (a = 0; a < channels; a++)
392
IMB_exr_add_channel(rl->exrhandle, rl->name, get_pass_name(passtype, a), 0, 0, NULL);
397
rpass->rect= MEM_mapallocN(sizeof(float)*rectsize, typestr);
398
rpass->rect = MEM_mapallocN(sizeof(float) * rectsize, typestr);
399
if (passtype==SCE_PASS_VECTOR) {
400
if (passtype == SCE_PASS_VECTOR) {
400
401
/* initialize to max speed */
402
for (x= rectsize-1; x>=0; x--)
403
rect[x]= PASS_VECTOR_MAX;
403
for (x = rectsize - 1; x >= 0; x--)
404
rect[x] = PASS_VECTOR_MAX;
405
else if (passtype==SCE_PASS_Z) {
407
for (x= rectsize-1; x>=0; x--)
406
else if (passtype == SCE_PASS_Z) {
408
for (x = rectsize - 1; x >= 0; x--)
414
415
/* will read info from Render *re to define layers */
415
416
/* called in threads */
416
417
/* re->winx,winy is coordinate space of entire image, partrct the part within */
417
RenderResult *render_result_new(Render *re, rcti *partrct, int crop, int savebuffers)
418
RenderResult *render_result_new(Render *re, rcti *partrct, int crop, int savebuffers, const char *layername)
419
420
RenderResult *rr;
421
422
SceneRenderLayer *srl;
422
423
int rectx, recty, nr;
424
rectx= partrct->xmax - partrct->xmin;
425
recty= partrct->ymax - partrct->ymin;
425
rectx = BLI_rcti_size_x(partrct);
426
recty = BLI_rcti_size_y(partrct);
427
if (rectx<=0 || recty<=0)
428
if (rectx <= 0 || recty <= 0)
430
rr= MEM_callocN(sizeof(RenderResult), "new render result");
433
rr->renrect.xmin = 0; rr->renrect.xmax = rectx-2*crop;
431
rr = MEM_callocN(sizeof(RenderResult), "new render result");
434
rr->renrect.xmin = 0; rr->renrect.xmax = rectx - 2 * crop;
434
435
/* crop is one or two extra pixels rendered for filtering, is used for merging and display too */
437
438
/* tilerect is relative coordinates within render disprect. do not subtract crop yet */
438
439
rr->tilerect.xmin = partrct->xmin - re->disprect.xmin;
439
rr->tilerect.xmax = partrct->xmax - re->disprect.xmax;
440
rr->tilerect.xmax = partrct->xmax - re->disprect.xmin;
440
441
rr->tilerect.ymin = partrct->ymin - re->disprect.ymin;
441
rr->tilerect.ymax = partrct->ymax - re->disprect.ymax;
442
rr->tilerect.ymax = partrct->ymax - re->disprect.ymin;
443
444
if (savebuffers) {
444
rr->exrhandle= IMB_exr_get_handle();
445
rr->do_exr_tile = TRUE;
447
448
/* check renderdata for amount of layers */
448
for (nr=0, srl= re->r.layers.first; srl; srl= srl->next, nr++) {
450
if ((re->r.scemode & R_SINGLE_LAYER) && nr!=re->r.actlay)
449
for (nr = 0, srl = re->r.layers.first; srl; srl = srl->next, nr++) {
451
if (layername && layername[0])
452
if (strcmp(srl->name, layername) != 0)
455
if ((re->r.scemode & R_SINGLE_LAYER) && nr != re->r.actlay)
452
457
if (srl->layflag & SCE_LAY_DISABLE)
455
rl= MEM_callocN(sizeof(RenderLayer), "new render layer");
460
rl = MEM_callocN(sizeof(RenderLayer), "new render layer");
456
461
BLI_addtail(&rr->layers, rl);
458
463
BLI_strncpy(rl->name, srl->name, sizeof(rl->name));
460
rl->lay_zmask= srl->lay_zmask;
461
rl->layflag= srl->layflag;
462
rl->passflag= srl->passflag; // for debugging: srl->passflag|SCE_PASS_RAYHITS;
463
rl->pass_xor= srl->pass_xor;
464
rl->light_override= srl->light_override;
465
rl->mat_override= srl->mat_override;
465
rl->lay_zmask = srl->lay_zmask;
466
rl->lay_exclude = srl->lay_exclude;
467
rl->layflag = srl->layflag;
468
rl->passflag = srl->passflag; /* for debugging: srl->passflag | SCE_PASS_RAYHITS; */
469
rl->pass_xor = srl->pass_xor;
470
rl->light_override = srl->light_override;
471
rl->mat_override = srl->mat_override;
470
IMB_exr_add_channel(rr->exrhandle, rl->name, "Combined.R", 0, 0, NULL);
471
IMB_exr_add_channel(rr->exrhandle, rl->name, "Combined.G", 0, 0, NULL);
472
IMB_exr_add_channel(rr->exrhandle, rl->name, "Combined.B", 0, 0, NULL);
473
IMB_exr_add_channel(rr->exrhandle, rl->name, "Combined.A", 0, 0, NULL);
475
if (rr->do_exr_tile) {
476
rl->exrhandle = IMB_exr_get_handle();
478
IMB_exr_add_channel(rl->exrhandle, rl->name, "Combined.R", 0, 0, NULL);
479
IMB_exr_add_channel(rl->exrhandle, rl->name, "Combined.G", 0, 0, NULL);
480
IMB_exr_add_channel(rl->exrhandle, rl->name, "Combined.B", 0, 0, NULL);
481
IMB_exr_add_channel(rl->exrhandle, rl->name, "Combined.A", 0, 0, NULL);
476
rl->rectf= MEM_mapallocN(rectx*recty*sizeof(float)*4, "Combined rgba");
484
rl->rectf = MEM_mapallocN(rectx * recty * sizeof(float) * 4, "Combined rgba");
478
486
if (srl->passflag & SCE_PASS_Z)
479
487
render_layer_add_pass(rr, rl, 1, SCE_PASS_Z);
534
542
/* sss, previewrender and envmap don't do layers, so we make a default one */
535
if (rr->layers.first==NULL) {
536
rl= MEM_callocN(sizeof(RenderLayer), "new render layer");
543
if (rr->layers.first == NULL && !(layername && layername[0])) {
544
rl = MEM_callocN(sizeof(RenderLayer), "new render layer");
537
545
BLI_addtail(&rr->layers, rl);
542
550
/* duplicate code... */
544
IMB_exr_add_channel(rr->exrhandle, rl->name, "Combined.R", 0, 0, NULL);
545
IMB_exr_add_channel(rr->exrhandle, rl->name, "Combined.G", 0, 0, NULL);
546
IMB_exr_add_channel(rr->exrhandle, rl->name, "Combined.B", 0, 0, NULL);
547
IMB_exr_add_channel(rr->exrhandle, rl->name, "Combined.A", 0, 0, NULL);
550
rl->rectf= MEM_mapallocN(rectx*recty*sizeof(float)*4, "Combined rgba");
551
if (rr->do_exr_tile) {
552
rl->exrhandle = IMB_exr_get_handle();
554
IMB_exr_add_channel(rl->exrhandle, rl->name, "Combined.R", 0, 0, NULL);
555
IMB_exr_add_channel(rl->exrhandle, rl->name, "Combined.G", 0, 0, NULL);
556
IMB_exr_add_channel(rl->exrhandle, rl->name, "Combined.B", 0, 0, NULL);
557
IMB_exr_add_channel(rl->exrhandle, rl->name, "Combined.A", 0, 0, NULL);
560
rl->rectf = MEM_mapallocN(rectx * recty * sizeof(float) * 4, "Combined rgba");
552
563
/* note, this has to be in sync with scene.c */
554
rl->layflag= 0x7FFF; /* solid ztra halo strand */
555
rl->passflag= SCE_PASS_COMBINED;
564
rl->lay = (1 << 20) - 1;
565
rl->layflag = 0x7FFF; /* solid ztra halo strand */
566
rl->passflag = SCE_PASS_COMBINED;
560
571
/* border render; calculate offset for use in compositor. compo is centralized coords */
561
rr->xof= re->disprect.xmin + (re->disprect.xmax - re->disprect.xmin)/2 - re->winx/2;
562
rr->yof= re->disprect.ymin + (re->disprect.ymax - re->disprect.ymin)/2 - re->winy/2;
572
rr->xof = re->disprect.xmin + BLI_rcti_cent_x(&re->disprect) - (re->winx / 2);
573
rr->yof = re->disprect.ymin + BLI_rcti_cent_y(&re->disprect) - (re->winy / 2);
573
return render_result_new(re, partrct, crop, savebuffers);
584
return render_result_new(re, partrct, crop, savebuffers, RR_ALL_LAYERS);
575
for (a=0; a<re->osa; a++) {
576
RenderResult *rr= render_result_new(re, partrct, crop, savebuffers);
586
for (a = 0; a < re->osa; a++) {
587
RenderResult *rr = render_result_new(re, partrct, crop, savebuffers, RR_ALL_LAYERS);
577
588
BLI_addtail(lb, rr);
581
592
return lb->first;
584
595
/* callbacks for render_result_new_from_exr */
585
static void *ml_addlayer_cb(void *base, char *str)
596
static void *ml_addlayer_cb(void *base, const char *str)
587
RenderResult *rr= base;
598
RenderResult *rr = base;
590
rl= MEM_callocN(sizeof(RenderLayer), "new render layer");
601
rl = MEM_callocN(sizeof(RenderLayer), "new render layer");
591
602
BLI_addtail(&rr->layers, rl);
593
604
BLI_strncpy(rl->name, str, EXR_LAY_MAXNAME);
597
static void ml_addpass_cb(void *UNUSED(base), void *lay, char *str, float *rect, int totchan, char *chan_id)
608
static void ml_addpass_cb(void *UNUSED(base), void *lay, const char *str, float *rect, int totchan, const char *chan_id)
599
RenderLayer *rl= lay;
600
RenderPass *rpass= MEM_callocN(sizeof(RenderPass), "loaded pass");
610
RenderLayer *rl = lay;
611
RenderPass *rpass = MEM_callocN(sizeof(RenderPass), "loaded pass");
603
614
BLI_addtail(&rl->passes, rpass);
604
rpass->channels= totchan;
615
rpass->channels = totchan;
606
rpass->passtype= passtype_from_name(str);
607
if (rpass->passtype==0) printf("unknown pass %s\n", str);
617
rpass->passtype = passtype_from_name(str);
618
if (rpass->passtype == 0) printf("unknown pass %s\n", str);
608
619
rl->passflag |= rpass->passtype;
610
621
BLI_strncpy(rpass->name, str, EXR_PASS_MAXNAME);
611
622
/* channel id chars */
612
for (a=0; a<totchan; a++)
613
rpass->chan_id[a]= chan_id[a];
623
for (a = 0; a < totchan; a++)
624
rpass->chan_id[a] = chan_id[a];
618
629
/* from imbuf, if a handle was returned we convert this to render result */
619
RenderResult *render_result_new_from_exr(void *exrhandle, int rectx, int recty)
630
RenderResult *render_result_new_from_exr(void *exrhandle, const char *colorspace, int predivide, int rectx, int recty)
621
RenderResult *rr= MEM_callocN(sizeof(RenderResult), "loaded render result");
632
RenderResult *rr = MEM_callocN(sizeof(RenderResult), __func__);
623
634
RenderPass *rpass;
635
const char *to_colorspace = IMB_colormanagement_role_colorspace_name_get(COLOR_ROLE_SCENE_LINEAR);
628
640
IMB_exr_multilayer_convert(exrhandle, rr, ml_addlayer_cb, ml_addpass_cb);
630
for (rl=rr->layers.first; rl; rl=rl->next) {
634
for (rpass=rl->passes.first; rpass; rpass=rpass->next) {
642
for (rl = rr->layers.first; rl; rl = rl->next) {
646
for (rpass = rl->passes.first; rpass; rpass = rpass->next) {
647
rpass->rectx = rectx;
648
rpass->recty = recty;
650
if (rpass->channels >= 3) {
651
IMB_colormanagement_transform(rpass->rect, rpass->rectx, rpass->recty, rpass->channels,
652
colorspace, to_colorspace, predivide);
718
740
RenderPass *rpass;
719
void *exrhandle= IMB_exr_get_handle();
741
void *exrhandle = IMB_exr_get_handle();
722
744
BLI_make_existing_file(filename);
724
746
/* composite result */
726
IMB_exr_add_channel(exrhandle, "Composite", "Combined.R", 4, 4*rr->rectx, rr->rectf);
727
IMB_exr_add_channel(exrhandle, "Composite", "Combined.G", 4, 4*rr->rectx, rr->rectf+1);
728
IMB_exr_add_channel(exrhandle, "Composite", "Combined.B", 4, 4*rr->rectx, rr->rectf+2);
729
IMB_exr_add_channel(exrhandle, "Composite", "Combined.A", 4, 4*rr->rectx, rr->rectf+3);
748
IMB_exr_add_channel(exrhandle, "Composite", "Combined.R", 4, 4 * rr->rectx, rr->rectf);
749
IMB_exr_add_channel(exrhandle, "Composite", "Combined.G", 4, 4 * rr->rectx, rr->rectf + 1);
750
IMB_exr_add_channel(exrhandle, "Composite", "Combined.B", 4, 4 * rr->rectx, rr->rectf + 2);
751
IMB_exr_add_channel(exrhandle, "Composite", "Combined.A", 4, 4 * rr->rectx, rr->rectf + 3);
732
754
/* add layers/passes and assign channels */
733
for (rl= rr->layers.first; rl; rl= rl->next) {
755
for (rl = rr->layers.first; rl; rl = rl->next) {
738
for (a=0; a<xstride; a++)
739
IMB_exr_add_channel(exrhandle, rl->name, get_pass_name(SCE_PASS_COMBINED, a),
740
xstride, xstride*rr->rectx, rl->rectf+a);
760
for (a = 0; a < xstride; a++) {
761
IMB_exr_add_channel(exrhandle, rl->name, get_pass_name(SCE_PASS_COMBINED, a),
762
xstride, xstride * rr->rectx, rl->rectf + a);
743
766
/* passes are allocated in sync */
744
for (rpass= rl->passes.first; rpass; rpass= rpass->next) {
745
int a, xstride= rpass->channels;
746
for (a=0; a<xstride; a++) {
748
IMB_exr_add_channel(exrhandle, rl->name, get_pass_name(rpass->passtype, a),
749
xstride, xstride*rr->rectx, rpass->rect+a);
751
IMB_exr_add_channel(exrhandle, rl->name, make_pass_name(rpass, a),
752
xstride, xstride*rr->rectx, rpass->rect+a);
767
for (rpass = rl->passes.first; rpass; rpass = rpass->next) {
768
int a, xstride = rpass->channels;
769
for (a = 0; a < xstride; a++) {
770
if (rpass->passtype) {
771
IMB_exr_add_channel(exrhandle, rl->name, get_pass_name(rpass->passtype, a),
772
xstride, xstride * rr->rectx, rpass->rect + a);
775
IMB_exr_add_channel(exrhandle, rl->name, make_pass_name(rpass, a),
776
xstride, xstride * rr->rectx, rpass->rect + a);
822
848
RE_FreeRenderResult(re->pushedresult);
823
re->pushedresult= NULL;
849
re->pushedresult = NULL;
826
852
/************************* EXR Tile File Rendering ***************************/
828
854
static void save_render_result_tile(RenderResult *rr, RenderResult *rrpart)
856
RenderLayer *rlp, *rl;
831
857
RenderPass *rpassp;
832
858
int offs, partx, party;
834
860
BLI_lock_thread(LOCK_IMAGE);
836
for (rlp= rrpart->layers.first; rlp; rlp= rlp->next) {
838
if (rrpart->crop) { /* filters add pixel extra */
839
offs= (rrpart->crop + rrpart->crop*rrpart->rectx);
862
for (rlp = rrpart->layers.first; rlp; rlp = rlp->next) {
863
rl = RE_GetRenderLayer(rr, rlp->name);
865
/* should never happen but prevents crash if it does */
867
if (UNLIKELY(rl == NULL)) {
871
if (rrpart->crop) { /* filters add pixel extra */
872
offs = (rrpart->crop + rrpart->crop * rrpart->rectx);
846
879
if (rlp->rectf) {
848
for (a=0; a<xstride; a++)
849
IMB_exr_set_channel(rr->exrhandle, rlp->name, get_pass_name(SCE_PASS_COMBINED, a),
850
xstride, xstride*rrpart->rectx, rlp->rectf+a + xstride*offs);
881
for (a = 0; a < xstride; a++) {
882
IMB_exr_set_channel(rl->exrhandle, rlp->name, get_pass_name(SCE_PASS_COMBINED, a),
883
xstride, xstride * rrpart->rectx, rlp->rectf + a + xstride * offs);
853
887
/* passes are allocated in sync */
854
for (rpassp= rlp->passes.first; rpassp; rpassp= rpassp->next) {
855
int a, xstride= rpassp->channels;
856
for (a=0; a<xstride; a++)
857
IMB_exr_set_channel(rr->exrhandle, rlp->name, get_pass_name(rpassp->passtype, a),
858
xstride, xstride*rrpart->rectx, rpassp->rect+a + xstride*offs);
888
for (rpassp = rlp->passes.first; rpassp; rpassp = rpassp->next) {
889
int a, xstride = rpassp->channels;
890
for (a = 0; a < xstride; a++) {
891
IMB_exr_set_channel(rl->exrhandle, rlp->name, get_pass_name(rpassp->passtype, a),
892
xstride, xstride * rrpart->rectx, rpassp->rect + a + xstride * offs);
863
party= rrpart->tilerect.ymin + rrpart->crop;
864
partx= rrpart->tilerect.xmin + rrpart->crop;
865
IMB_exrtile_write_channels(rr->exrhandle, partx, party, 0);
898
party = rrpart->tilerect.ymin + rrpart->crop;
899
partx = rrpart->tilerect.xmin + rrpart->crop;
901
for (rlp = rrpart->layers.first; rlp; rlp = rlp->next) {
902
rl = RE_GetRenderLayer(rr, rlp->name);
904
/* should never happen but prevents crash if it does */
906
if (UNLIKELY(rl == NULL)) {
910
IMB_exrtile_write_channels(rl->exrhandle, partx, party, 0);
867
913
BLI_unlock_thread(LOCK_IMAGE);
920
976
/* save part into exr file */
921
977
void render_result_exr_file_merge(RenderResult *rr, RenderResult *rrpart)
923
for (; rr && rrpart; rr= rr->next, rrpart= rrpart->next)
979
for (; rr && rrpart; rr = rr->next, rrpart = rrpart->next)
924
980
save_render_result_tile(rr, rrpart);
927
983
/* path to temporary exr file */
928
void render_result_exr_file_path(Scene *scene, int sample, char *filepath)
984
void render_result_exr_file_path(Scene *scene, const char *layname, int sample, char *filepath)
930
char di[FILE_MAX], name[FILE_MAXFILE+MAX_ID_NAME+100], fi[FILE_MAXFILE];
986
char di[FILE_MAX], name[FILE_MAXFILE + MAX_ID_NAME + MAX_ID_NAME + 100], fi[FILE_MAXFILE];
932
988
BLI_strncpy(di, G.main->name, FILE_MAX);
933
989
BLI_splitdirstring(di, fi);
936
BLI_snprintf(name, sizeof(name), "%s_%s.exr", fi, scene->id.name+2);
992
BLI_snprintf(name, sizeof(name), "%s_%s_%s.exr", fi, scene->id.name + 2, layname);
938
BLI_snprintf(name, sizeof(name), "%s_%s%d.exr", fi, scene->id.name+2, sample);
994
BLI_snprintf(name, sizeof(name), "%s_%s_%s%d.exr", fi, scene->id.name + 2, layname, sample);
940
996
BLI_make_file_string("/", filepath, BLI_temporary_dir(), name);
943
999
/* only for temp buffer files, makes exact copy of render result */
944
1000
int render_result_exr_file_read(Render *re, int sample)
946
1003
char str[FILE_MAX];
949
1006
RE_FreeRenderResult(re->result);
950
re->result= render_result_new(re, &re->disprect, 0, RR_USE_MEM);
952
render_result_exr_file_path(re->scene, sample, str);
953
printf("read exr tmp file: %s\n", str);
955
if (render_result_exr_file_read_path(re->result, str)) {
959
printf("cannot read: %s\n", str);
1007
re->result = render_result_new(re, &re->disprect, 0, RR_USE_MEM, RR_ALL_LAYERS);
1009
for (rl = re->result->layers.first; rl; rl = rl->next) {
1011
render_result_exr_file_path(re->scene, rl->name, sample, str);
1012
printf("read exr tmp file: %s\n", str);
1014
if (!render_result_exr_file_read_path(re->result, rl, str)) {
1015
printf("cannot read: %s\n", str);
967
1024
/* called for reading temp files, and for external engines */
968
int render_result_exr_file_read_path(RenderResult *rr, const char *filepath)
1025
int render_result_exr_file_read_path(RenderResult *rr, RenderLayer *rl_single, const char *filepath)
970
1027
RenderLayer *rl;
971
1028
RenderPass *rpass;
972
void *exrhandle= IMB_exr_get_handle();
1029
void *exrhandle = IMB_exr_get_handle();
973
1030
int rectx, recty;
975
if (IMB_exr_begin_read(exrhandle, filepath, &rectx, &recty)==0) {
1032
if (IMB_exr_begin_read(exrhandle, filepath, &rectx, &recty) == 0) {
976
1033
printf("failed being read %s\n", filepath);
977
1034
IMB_exr_close(exrhandle);
981
if (rr == NULL || rectx!=rr->rectx || recty!=rr->recty) {
1038
if (rr == NULL || rectx != rr->rectx || recty != rr->recty) {
983
1040
printf("error in reading render result: dimensions don't match\n");
1018
1078
ImBuf *render_result_rect_to_ibuf(RenderResult *rr, RenderData *rd)
1020
int flags = (rd->color_mgt_flag & R_COLOR_MANAGEMENT_PREDIVIDE)? IB_cm_predivide: 0;
1021
ImBuf *ibuf= IMB_allocImBuf(rr->rectx, rr->recty, rd->im_format.planes, flags);
1080
ImBuf *ibuf = IMB_allocImBuf(rr->rectx, rr->recty, rd->im_format.planes, 0);
1023
/* if not exists, BKE_write_ibuf makes one */
1024
ibuf->rect= (unsigned int *)rr->rect32;
1025
ibuf->rect_float= rr->rectf;
1026
ibuf->zbuf_float= rr->rectz;
1082
/* if not exists, BKE_imbuf_write makes one */
1083
ibuf->rect = (unsigned int *)rr->rect32;
1084
ibuf->rect_float = rr->rectf;
1085
ibuf->zbuf_float = rr->rectz;
1028
1087
/* float factor for random dither, imbuf takes care of it */
1029
ibuf->dither= rd->dither_intensity;
1088
ibuf->dither = rd->dither_intensity;
1031
/* prepare to gamma correct to sRGB color space */
1032
if (rd->color_mgt_flag & R_COLOR_MANAGEMENT) {
1033
/* sequence editor can generate 8bpc render buffers */
1035
ibuf->profile = IB_PROFILE_SRGB;
1036
if (BKE_imtype_valid_depths(rd->im_format.imtype) & (R_IMF_CHAN_DEPTH_12|R_IMF_CHAN_DEPTH_16|R_IMF_CHAN_DEPTH_24|R_IMF_CHAN_DEPTH_32))
1037
IMB_float_from_rect(ibuf);
1090
/* prepare to gamma correct to sRGB color space
1091
* note that sequence editor can generate 8bpc render buffers
1094
if (BKE_imtype_valid_depths(rd->im_format.imtype) & (R_IMF_CHAN_DEPTH_12 | R_IMF_CHAN_DEPTH_16 | R_IMF_CHAN_DEPTH_24 | R_IMF_CHAN_DEPTH_32)) {
1095
IMB_float_from_rect(ibuf);
1040
ibuf->profile = IB_PROFILE_LINEAR_RGB;
1098
/* ensure no float buffer remained from previous frame */
1099
ibuf->rect_float = NULL;
1044
/* color -> greyscale */
1103
/* color -> grayscale */
1045
1104
/* editing directly would alter the render view */
1046
1105
if (rd->im_format.planes == R_IMF_PLANES_BW) {
1047
ImBuf *ibuf_bw= IMB_dupImBuf(ibuf);
1106
ImBuf *ibuf_bw = IMB_dupImBuf(ibuf);
1048
1107
IMB_color_to_bw(ibuf_bw);
1049
1108
IMB_freeImBuf(ibuf);
1056
void render_result_rect_from_ibuf(RenderResult *rr, RenderData *rd, ImBuf *ibuf)
1115
void render_result_rect_from_ibuf(RenderResult *rr, RenderData *UNUSED(rd), ImBuf *ibuf)
1058
1117
if (ibuf->rect_float) {
1059
/* color management: when off ensure rectf is non-lin, since thats what the internal
1060
* render engine delivers */
1061
int profile_to= (rd->color_mgt_flag & R_COLOR_MANAGEMENT)? IB_PROFILE_LINEAR_RGB: IB_PROFILE_SRGB;
1062
int profile_from= (ibuf->profile == IB_PROFILE_LINEAR_RGB)? IB_PROFILE_LINEAR_RGB: IB_PROFILE_SRGB;
1063
int predivide= (rd->color_mgt_flag & R_COLOR_MANAGEMENT_PREDIVIDE);
1065
1118
if (!rr->rectf)
1066
rr->rectf= MEM_mallocN(4*sizeof(float)*rr->rectx*rr->recty, "render_seq rectf");
1068
IMB_buffer_float_from_float(rr->rectf, ibuf->rect_float,
1069
4, profile_to, profile_from, predivide,
1070
rr->rectx, rr->recty, rr->rectx, rr->rectx);
1119
rr->rectf = MEM_mallocN(4 * sizeof(float) * rr->rectx * rr->recty, "render_seq rectf");
1121
memcpy(rr->rectf, ibuf->rect_float, 4 * sizeof(float) * rr->rectx * rr->recty);
1072
1123
/* TSK! Since sequence render doesn't free the *rr render result, the old rect32
1073
1124
* can hang around when sequence render has rendered a 32 bits one before */
1074
1125
if (rr->rect32) {
1075
1126
MEM_freeN(rr->rect32);
1079
1130
else if (ibuf->rect) {
1080
1131
if (!rr->rect32)
1081
rr->rect32= MEM_mallocN(sizeof(int)*rr->rectx*rr->recty, "render_seq rect");
1132
rr->rect32 = MEM_mallocN(sizeof(int) * rr->rectx * rr->recty, "render_seq rect");
1083
memcpy(rr->rect32, ibuf->rect, 4*rr->rectx*rr->recty);
1134
memcpy(rr->rect32, ibuf->rect, 4 * rr->rectx * rr->recty);
1085
1136
/* Same things as above, old rectf can hang around from previous render. */
1086
1137
if (rr->rectf) {
1087
1138
MEM_freeN(rr->rectf);
1093
1144
void render_result_rect_fill_zero(RenderResult *rr)
1096
memset(rr->rectf, 0, 4*sizeof(float)*rr->rectx*rr->recty);
1147
memset(rr->rectf, 0, 4 * sizeof(float) * rr->rectx * rr->recty);
1097
1148
else if (rr->rect32)
1098
memset(rr->rect32, 0, 4*rr->rectx*rr->recty);
1149
memset(rr->rect32, 0, 4 * rr->rectx * rr->recty);
1100
rr->rect32= MEM_callocN(sizeof(int)*rr->rectx*rr->recty, "render_seq rect");
1151
rr->rect32 = MEM_callocN(sizeof(int) * rr->rectx * rr->recty, "render_seq rect");
1103
void render_result_rect_get_pixels(RenderResult *rr, RenderData *rd, unsigned int *rect, int rectx, int recty)
1154
void render_result_rect_get_pixels(RenderResult *rr, unsigned int *rect, int rectx, int recty,
1155
const ColorManagedViewSettings *view_settings, const ColorManagedDisplaySettings *display_settings)
1105
1157
if (rr->rect32) {
1106
memcpy(rect, rr->rect32, sizeof(int)*rr->rectx*rr->recty);
1158
memcpy(rect, rr->rect32, sizeof(int) * rr->rectx * rr->recty);
1108
1160
else if (rr->rectf) {
1109
int profile_from= (rd->color_mgt_flag & R_COLOR_MANAGEMENT)? IB_PROFILE_LINEAR_RGB: IB_PROFILE_SRGB;
1110
int predivide= (rd->color_mgt_flag & R_COLOR_MANAGEMENT_PREDIVIDE);
1113
IMB_buffer_byte_from_float((unsigned char*)rect, rr->rectf,
1114
4, dither, IB_PROFILE_SRGB, profile_from, predivide,
1115
rr->rectx, rr->recty, rr->rectx, rr->rectx);
1161
IMB_display_buffer_transform_apply((unsigned char *) rect, rr->rectf, rr->rectx, rr->recty, 4,
1162
view_settings, display_settings, TRUE);
1118
1165
/* else fill with black */
1119
memset(rect, 0, sizeof(int)*rectx*recty);
1166
memset(rect, 0, sizeof(int) * rectx * recty);