~ubuntu-branches/ubuntu/trusty/blender/trusty

« back to all changes in this revision

Viewing changes to source/blender/render/intern/source/render_result.c

  • Committer: Package Import Robot
  • Author(s): Jeremy Bicha
  • Date: 2013-03-06 12:08:47 UTC
  • mfrom: (1.5.1) (14.1.8 experimental)
  • Revision ID: package-import@ubuntu.com-20130306120847-frjfaryb2zrotwcg
Tags: 2.66a-1ubuntu1
* Resynchronize with Debian (LP: #1076930, #1089256, #1052743, #999024,
  #1122888, #1147084)
* debian/control:
  - Lower build-depends on libavcodec-dev since we're not
    doing the libav9 transition in Ubuntu yet

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*  
2
 
 *
 
1
/*
3
2
 * ***** BEGIN GPL LICENSE BLOCK *****
4
3
 *
5
4
 * This program is free software; you can redistribute it and/or
31
30
 */
32
31
 
33
32
#include <stdio.h>
 
33
#include <stdlib.h>
34
34
#include <string.h>
35
35
 
36
36
#include "MEM_guardedalloc.h"
37
37
 
38
 
#include "BKE_image.h"
39
 
#include "BKE_global.h"
40
 
#include "BKE_main.h"
41
 
#include "BKE_report.h"
42
 
#include "BKE_utildefines.h"
43
 
 
44
38
#include "BLI_fileops.h"
45
39
#include "BLI_listbase.h"
46
40
#include "BLI_path_util.h"
 
41
#include "BLI_rect.h"
47
42
#include "BLI_string.h"
48
43
#include "BLI_threads.h"
49
44
#include "BLI_utildefines.h"
50
45
 
 
46
#include "BKE_image.h"
 
47
#include "BKE_global.h"
 
48
#include "BKE_main.h"
 
49
#include "BKE_report.h"
 
50
 
51
51
#include "IMB_imbuf.h"
52
52
#include "IMB_imbuf_types.h"
 
53
#include "IMB_colormanagement.h"
53
54
 
54
55
#include "intern/openexr/openexr_multi.h"
55
56
 
60
61
 
61
62
void render_result_free(RenderResult *res)
62
63
{
63
 
        if (res==NULL) return;
 
64
        if (res == NULL) return;
64
65
 
65
66
        while (res->layers.first) {
66
 
                RenderLayer *rl= res->layers.first;
 
67
                RenderLayer *rl = res->layers.first;
67
68
                
68
69
                if (rl->rectf) MEM_freeN(rl->rectf);
69
70
                /* acolrect and scolrect are optionally allocated in shade_tile, only free here since it can be used for drawing */
71
72
                if (rl->scolrect) MEM_freeN(rl->scolrect);
72
73
                
73
74
                while (rl->passes.first) {
74
 
                        RenderPass *rpass= rl->passes.first;
 
75
                        RenderPass *rpass = rl->passes.first;
75
76
                        if (rpass->rect) MEM_freeN(rpass->rect);
76
77
                        BLI_remlink(&rl->passes, rpass);
77
78
                        MEM_freeN(rpass);
97
98
{
98
99
        RenderResult *rrnext;
99
100
        
100
 
        for (; rr; rr= rrnext) {
101
 
                rrnext= rr->next;
 
101
        for (; rr; rr = rrnext) {
 
102
                rrnext = rr->next;
102
103
                
103
104
                if (lb && lb->first)
104
105
                        BLI_remlink(lb, rr);
115
116
{
116
117
        
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";
123
124
        }
124
125
        if (passtype == SCE_PASS_Z) {
125
 
                if (channel==-1) return "Depth";
 
126
                if (channel == -1) return "Depth";
126
127
                return "Depth.Z";
127
128
        }
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";
134
135
        }
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";
140
141
        }
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";
145
146
                return "UV.A";
146
147
        }
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";
153
154
        }
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";
158
159
                return "Emit.B";
159
160
        }
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";
165
166
        }
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";
170
171
                return "Spec.B";
171
172
        }
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";
177
178
        }
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";
182
183
                return "AO.B";
183
184
        }
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";
188
189
                return "Env.B";
189
190
        }
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";
195
196
        }
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";
201
202
        }
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";
207
208
        }
208
209
        if (passtype == SCE_PASS_INDEXOB) {
209
 
                if (channel==-1) return "IndexOB";
 
210
                if (channel == -1) return "IndexOB";
210
211
                return "IndexOB.X";
211
212
        }
212
213
        if (passtype == SCE_PASS_INDEXMA) {
213
 
                if (channel==-1) return "IndexMA";
 
214
                if (channel == -1) return "IndexMA";
214
215
                return "IndexMA.X";
215
216
        }
216
217
        if (passtype == SCE_PASS_MIST) {
217
 
                if (channel==-1) return "Mist";
 
218
                if (channel == -1) return "Mist";
218
219
                return "Mist.Z";
219
220
        }
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";
225
226
        }
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";
231
232
        }
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";
237
238
        }
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";
243
244
        }
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";
249
250
        }
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";
255
256
        }
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";
261
262
        }
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";
267
268
        }
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";
273
274
        }
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";
279
280
        }
280
281
        return "Unknown";
283
284
static int passtype_from_name(const char *str)
284
285
{
285
286
        
286
 
        if (strcmp(str, "Combined")==0)
 
287
        if (strcmp(str, "Combined") == 0)
287
288
                return SCE_PASS_COMBINED;
288
289
 
289
 
        if (strcmp(str, "Depth")==0)
 
290
        if (strcmp(str, "Depth") == 0)
290
291
                return SCE_PASS_Z;
291
292
 
292
 
        if (strcmp(str, "Vector")==0)
 
293
        if (strcmp(str, "Vector") == 0)
293
294
                return SCE_PASS_VECTOR;
294
295
 
295
 
        if (strcmp(str, "Normal")==0)
 
296
        if (strcmp(str, "Normal") == 0)
296
297
                return SCE_PASS_NORMAL;
297
298
 
298
 
        if (strcmp(str, "UV")==0)
 
299
        if (strcmp(str, "UV") == 0)
299
300
                return SCE_PASS_UV;
300
301
 
301
 
        if (strcmp(str, "Color")==0)
 
302
        if (strcmp(str, "Color") == 0)
302
303
                return SCE_PASS_RGBA;
303
304
 
304
 
        if (strcmp(str, "Emit")==0)
 
305
        if (strcmp(str, "Emit") == 0)
305
306
                return SCE_PASS_EMIT;
306
307
 
307
 
        if (strcmp(str, "Diffuse")==0)
 
308
        if (strcmp(str, "Diffuse") == 0)
308
309
                return SCE_PASS_DIFFUSE;
309
310
 
310
 
        if (strcmp(str, "Spec")==0)
 
311
        if (strcmp(str, "Spec") == 0)
311
312
                return SCE_PASS_SPEC;
312
313
 
313
 
        if (strcmp(str, "Shadow")==0)
 
314
        if (strcmp(str, "Shadow") == 0)
314
315
                return SCE_PASS_SHADOW;
315
316
        
316
 
        if (strcmp(str, "AO")==0)
 
317
        if (strcmp(str, "AO") == 0)
317
318
                return SCE_PASS_AO;
318
319
 
319
 
        if (strcmp(str, "Env")==0)
 
320
        if (strcmp(str, "Env") == 0)
320
321
                return SCE_PASS_ENVIRONMENT;
321
322
 
322
 
        if (strcmp(str, "Indirect")==0)
 
323
        if (strcmp(str, "Indirect") == 0)
323
324
                return SCE_PASS_INDIRECT;
324
325
 
325
 
        if (strcmp(str, "Reflect")==0)
 
326
        if (strcmp(str, "Reflect") == 0)
326
327
                return SCE_PASS_REFLECT;
327
328
 
328
 
        if (strcmp(str, "Refract")==0)
 
329
        if (strcmp(str, "Refract") == 0)
329
330
                return SCE_PASS_REFRACT;
330
331
 
331
 
        if (strcmp(str, "IndexOB")==0)
 
332
        if (strcmp(str, "IndexOB") == 0)
332
333
                return SCE_PASS_INDEXOB;
333
334
 
334
 
        if (strcmp(str, "IndexMA")==0)
 
335
        if (strcmp(str, "IndexMA") == 0)
335
336
                return SCE_PASS_INDEXMA;
336
337
 
337
 
        if (strcmp(str, "Mist")==0)
 
338
        if (strcmp(str, "Mist") == 0)
338
339
                return SCE_PASS_MIST;
339
340
        
340
 
        if (strcmp(str, "RayHits")==0)
 
341
        if (strcmp(str, "RayHits") == 0)
341
342
                return SCE_PASS_RAYHITS;
342
343
 
343
 
        if (strcmp(str, "DiffDir")==0)
 
344
        if (strcmp(str, "DiffDir") == 0)
344
345
                return SCE_PASS_DIFFUSE_DIRECT;
345
346
 
346
 
        if (strcmp(str, "DiffInd")==0)
 
347
        if (strcmp(str, "DiffInd") == 0)
347
348
                return SCE_PASS_DIFFUSE_INDIRECT;
348
349
 
349
 
        if (strcmp(str, "DiffCol")==0)
 
350
        if (strcmp(str, "DiffCol") == 0)
350
351
                return SCE_PASS_DIFFUSE_COLOR;
351
352
 
352
 
        if (strcmp(str, "GlossDir")==0)
 
353
        if (strcmp(str, "GlossDir") == 0)
353
354
                return SCE_PASS_GLOSSY_DIRECT;
354
355
 
355
 
        if (strcmp(str, "GlossInd")==0)
 
356
        if (strcmp(str, "GlossInd") == 0)
356
357
                return SCE_PASS_GLOSSY_INDIRECT;
357
358
 
358
 
        if (strcmp(str, "GlossCol")==0)
 
359
        if (strcmp(str, "GlossCol") == 0)
359
360
                return SCE_PASS_GLOSSY_COLOR;
360
361
 
361
 
        if (strcmp(str, "TransDir")==0)
 
362
        if (strcmp(str, "TransDir") == 0)
362
363
                return SCE_PASS_TRANSM_DIRECT;
363
364
 
364
 
        if (strcmp(str, "TransInd")==0)
 
365
        if (strcmp(str, "TransInd") == 0)
365
366
                return SCE_PASS_TRANSM_INDIRECT;
366
367
 
367
 
        if (strcmp(str, "TransCol")==0)
 
368
        if (strcmp(str, "TransCol") == 0)
368
369
                return SCE_PASS_TRANSM_COLOR;
369
370
 
370
371
        return 0;
374
375
 
375
376
static void render_layer_add_pass(RenderResult *rr, RenderLayer *rl, int channels, int passtype)
376
377
{
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;
380
381
        
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));
387
388
        
388
 
        if (rr->exrhandle) {
 
389
        if (rl->exrhandle) {
389
390
                int a;
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);
392
393
        }
393
394
        else {
394
395
                float *rect;
395
396
                int x;
396
397
                
397
 
                rpass->rect= MEM_mapallocN(sizeof(float)*rectsize, typestr);
 
398
                rpass->rect = MEM_mapallocN(sizeof(float) * rectsize, typestr);
398
399
                
399
 
                if (passtype==SCE_PASS_VECTOR) {
 
400
                if (passtype == SCE_PASS_VECTOR) {
400
401
                        /* initialize to max speed */
401
 
                        rect= rpass->rect;
402
 
                        for (x= rectsize-1; x>=0; x--)
403
 
                                rect[x]= PASS_VECTOR_MAX;
 
402
                        rect = rpass->rect;
 
403
                        for (x = rectsize - 1; x >= 0; x--)
 
404
                                rect[x] = PASS_VECTOR_MAX;
404
405
                }
405
 
                else if (passtype==SCE_PASS_Z) {
406
 
                        rect= rpass->rect;
407
 
                        for (x= rectsize-1; x>=0; x--)
408
 
                                rect[x]= 10e10;
 
406
                else if (passtype == SCE_PASS_Z) {
 
407
                        rect = rpass->rect;
 
408
                        for (x = rectsize - 1; x >= 0; x--)
 
409
                                rect[x] = 10e10;
409
410
                }
410
411
        }
411
412
}
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)
418
419
{
419
420
        RenderResult *rr;
420
421
        RenderLayer *rl;
421
422
        SceneRenderLayer *srl;
422
423
        int rectx, recty, nr;
423
424
        
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);
426
427
        
427
 
        if (rectx<=0 || recty<=0)
 
428
        if (rectx <= 0 || recty <= 0)
428
429
                return NULL;
429
430
        
430
 
        rr= MEM_callocN(sizeof(RenderResult), "new render result");
431
 
        rr->rectx= rectx;
432
 
        rr->recty= recty;
433
 
        rr->renrect.xmin = 0; rr->renrect.xmax = rectx-2*crop;
 
431
        rr = MEM_callocN(sizeof(RenderResult), "new render result");
 
432
        rr->rectx = rectx;
 
433
        rr->recty = recty;
 
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 */
435
 
        rr->crop= crop;
436
 
        
 
436
        rr->crop = crop;
 
437
 
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;
442
443
        
443
444
        if (savebuffers) {
444
 
                rr->exrhandle= IMB_exr_get_handle();
 
445
                rr->do_exr_tile = TRUE;
445
446
        }
446
 
        
 
447
 
447
448
        /* check renderdata for amount of layers */
448
 
        for (nr=0, srl= re->r.layers.first; srl; srl= srl->next, nr++) {
449
 
                
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++) {
 
450
 
 
451
                if (layername && layername[0])
 
452
                        if (strcmp(srl->name, layername) != 0)
 
453
                                continue;
 
454
 
 
455
                if ((re->r.scemode & R_SINGLE_LAYER) && nr != re->r.actlay)
451
456
                        continue;
452
457
                if (srl->layflag & SCE_LAY_DISABLE)
453
458
                        continue;
454
459
                
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);
457
462
                
458
463
                BLI_strncpy(rl->name, srl->name, sizeof(rl->name));
459
 
                rl->lay= srl->lay;
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;
466
 
                rl->rectx= rectx;
467
 
                rl->recty= recty;
 
464
                rl->lay = srl->lay;
 
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;
 
472
                rl->rectx = rectx;
 
473
                rl->recty = recty;
468
474
                
469
 
                if (rr->exrhandle) {
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();
 
477
 
 
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);
474
482
                }
475
483
                else
476
 
                        rl->rectf= MEM_mapallocN(rectx*recty*sizeof(float)*4, "Combined rgba");
 
484
                        rl->rectf = MEM_mapallocN(rectx * recty * sizeof(float) * 4, "Combined rgba");
477
485
                
478
486
                if (srl->passflag  & SCE_PASS_Z)
479
487
                        render_layer_add_pass(rr, rl, 1, SCE_PASS_Z);
532
540
                
533
541
        }
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);
538
546
                
539
 
                rl->rectx= rectx;
540
 
                rl->recty= recty;
 
547
                rl->rectx = rectx;
 
548
                rl->recty = recty;
541
549
 
542
550
                /* duplicate code... */
543
 
                if (rr->exrhandle) {
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);
548
 
                }
549
 
                else
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();
 
553
 
 
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);
 
558
                }
 
559
                else {
 
560
                        rl->rectf = MEM_mapallocN(rectx * recty * sizeof(float) * 4, "Combined rgba");
 
561
                }
551
562
                
552
563
                /* note, this has to be in sync with scene.c */
553
 
                rl->lay= (1<<20) -1;
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;
556
567
                
557
 
                re->r.actlay= 0;
 
568
                re->r.actlay = 0;
558
569
        }
559
570
        
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);
563
574
        
564
575
        return rr;
565
576
}
569
580
{
570
581
        int a;
571
582
        
572
 
        if (re->osa==0)
573
 
                return render_result_new(re, partrct, crop, savebuffers);
 
583
        if (re->osa == 0)
 
584
                return render_result_new(re, partrct, crop, savebuffers, RR_ALL_LAYERS);
574
585
        
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);
578
 
                rr->sample_nr= a;
 
589
                rr->sample_nr = a;
579
590
        }
580
591
        
581
592
        return lb->first;
582
593
}
583
594
 
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)
586
597
{
587
 
        RenderResult *rr= base;
 
598
        RenderResult *rr = base;
588
599
        RenderLayer *rl;
589
600
        
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);
592
603
        
593
604
        BLI_strncpy(rl->name, str, EXR_LAY_MAXNAME);
594
605
        return rl;
595
606
}
596
607
 
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)
598
609
{
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");
601
612
        int a;
602
613
        
603
614
        BLI_addtail(&rl->passes, rpass);
604
 
        rpass->channels= totchan;
 
615
        rpass->channels = totchan;
605
616
 
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;
609
620
        
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];
614
625
        
615
 
        rpass->rect= rect;
 
626
        rpass->rect = rect;
616
627
}
617
628
 
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)
620
631
{
621
 
        RenderResult *rr= MEM_callocN(sizeof(RenderResult), "loaded render result");
 
632
        RenderResult *rr = MEM_callocN(sizeof(RenderResult), __func__);
622
633
        RenderLayer *rl;
623
634
        RenderPass *rpass;
624
 
        
625
 
        rr->rectx= rectx;
626
 
        rr->recty= recty;
 
635
        const char *to_colorspace = IMB_colormanagement_role_colorspace_name_get(COLOR_ROLE_SCENE_LINEAR);
 
636
 
 
637
        rr->rectx = rectx;
 
638
        rr->recty = recty;
627
639
        
628
640
        IMB_exr_multilayer_convert(exrhandle, rr, ml_addlayer_cb, ml_addpass_cb);
629
641
 
630
 
        for (rl=rr->layers.first; rl; rl=rl->next) {
631
 
                rl->rectx= rectx;
632
 
                rl->recty= recty;
633
 
 
634
 
                for (rpass=rl->passes.first; rpass; rpass=rpass->next) {
635
 
                        rpass->rectx= rectx;
636
 
                        rpass->recty= recty;
 
642
        for (rl = rr->layers.first; rl; rl = rl->next) {
 
643
                rl->rectx = rectx;
 
644
                rl->recty = recty;
 
645
 
 
646
                for (rpass = rl->passes.first; rpass; rpass = rpass->next) {
 
647
                        rpass->rectx = rectx;
 
648
                        rpass->recty = recty;
 
649
 
 
650
                        if (rpass->channels >= 3) {
 
651
                                IMB_colormanagement_transform(rpass->rect, rpass->rectx, rpass->recty, rpass->channels,
 
652
                                                              colorspace, to_colorspace, predivide);
 
653
                        }
637
654
                }
638
655
        }
639
656
        
646
663
{
647
664
        int y, ofs, copylen, tilex, tiley;
648
665
        
649
 
        copylen= tilex= rrpart->rectx;
650
 
        tiley= rrpart->recty;
 
666
        copylen = tilex = rrpart->rectx;
 
667
        tiley = rrpart->recty;
651
668
        
652
 
        if (rrpart->crop) {     /* filters add pixel extra */
653
 
                tile+= pixsize*(rrpart->crop + rrpart->crop*tilex);
654
 
                
655
 
                copylen= tilex - 2*rrpart->crop;
656
 
                tiley -= 2*rrpart->crop;
657
 
                
658
 
                ofs= (rrpart->tilerect.ymin + rrpart->crop)*rr->rectx + (rrpart->tilerect.xmin+rrpart->crop);
659
 
                target+= pixsize*ofs;
 
669
        if (rrpart->crop) { /* filters add pixel extra */
 
670
                tile += pixsize * (rrpart->crop + rrpart->crop * tilex);
 
671
                
 
672
                copylen = tilex - 2 * rrpart->crop;
 
673
                tiley -= 2 * rrpart->crop;
 
674
                
 
675
                ofs = (rrpart->tilerect.ymin + rrpart->crop) * rr->rectx + (rrpart->tilerect.xmin + rrpart->crop);
 
676
                target += pixsize * ofs;
660
677
        }
661
678
        else {
662
 
                ofs= (rrpart->tilerect.ymin*rr->rectx + rrpart->tilerect.xmin);
663
 
                target+= pixsize*ofs;
 
679
                ofs = (rrpart->tilerect.ymin * rr->rectx + rrpart->tilerect.xmin);
 
680
                target += pixsize * ofs;
664
681
        }
665
682
 
666
 
        copylen *= sizeof(float)*pixsize;
 
683
        copylen *= sizeof(float) * pixsize;
667
684
        tilex *= pixsize;
668
 
        ofs= pixsize*rr->rectx;
 
685
        ofs = pixsize * rr->rectx;
669
686
 
670
 
        for (y=0; y<tiley; y++) {
 
687
        for (y = 0; y < tiley; y++) {
671
688
                memcpy(target, tile, copylen);
672
 
                target+= ofs;
673
 
                tile+= tilex;
 
689
                target += ofs;
 
690
                tile += tilex;
674
691
        }
675
692
}
676
693
 
682
699
        RenderLayer *rl, *rlp;
683
700
        RenderPass *rpass, *rpassp;
684
701
        
685
 
        for (rl= rr->layers.first, rlp= rrpart->layers.first; rl && rlp; rl= rl->next, rlp= rlp->next) {
686
 
                
687
 
                /* combined */
688
 
                if (rl->rectf && rlp->rectf)
689
 
                        do_merge_tile(rr, rrpart, rl->rectf, rlp->rectf, 4);
690
 
                
691
 
                /* passes are allocated in sync */
692
 
                for (rpass= rl->passes.first, rpassp= rlp->passes.first; rpass && rpassp; rpass= rpass->next, rpassp= rpassp->next) {
693
 
                        do_merge_tile(rr, rrpart, rpass->rect, rpassp->rect, rpass->channels);
 
702
        for (rl = rr->layers.first; rl; rl = rl->next) {
 
703
                rlp = RE_GetRenderLayer(rrpart, rl->name);
 
704
                if (rlp) {
 
705
                        /* combined */
 
706
                        if (rl->rectf && rlp->rectf)
 
707
                                do_merge_tile(rr, rrpart, rl->rectf, rlp->rectf, 4);
 
708
 
 
709
                        /* passes are allocated in sync */
 
710
                        for (rpass = rl->passes.first, rpassp = rlp->passes.first;
 
711
                             rpass && rpassp;
 
712
                             rpass = rpass->next, rpassp = rpassp->next)
 
713
                        {
 
714
                                do_merge_tile(rr, rrpart, rpass->rect, rpassp->rect, rpass->channels);
 
715
                        }
694
716
                }
695
717
        }
696
718
}
702
724
        int len;
703
725
        
704
726
        BLI_strncpy(name, rpass->name, EXR_PASS_MAXNAME);
705
 
        len= strlen(name);
706
 
        name[len]= '.';
707
 
        name[len+1]= rpass->chan_id[chan];
708
 
        name[len+2]= 0;
 
727
        len = strlen(name);
 
728
        name[len] = '.';
 
729
        name[len + 1] = rpass->chan_id[chan];
 
730
        name[len + 2] = 0;
709
731
 
710
732
        return name;
711
733
}
716
738
{
717
739
        RenderLayer *rl;
718
740
        RenderPass *rpass;
719
 
        void *exrhandle= IMB_exr_get_handle();
 
741
        void *exrhandle = IMB_exr_get_handle();
720
742
        int success;
721
743
 
722
744
        BLI_make_existing_file(filename);
723
745
        
724
746
        /* composite result */
725
747
        if (rr->rectf) {
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);
730
752
        }
731
753
        
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) {
734
756
                
735
757
                /* combined */
736
758
                if (rl->rectf) {
737
 
                        int a, xstride= 4;
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);
 
759
                        int a, xstride = 4;
 
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);
 
763
                        }
741
764
                }
742
765
                
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++) {
747
 
                                if (rpass->passtype)
748
 
                                        IMB_exr_add_channel(exrhandle, rl->name, get_pass_name(rpass->passtype, a), 
749
 
                                                                                xstride, xstride*rr->rectx, rpass->rect+a);
750
 
                                else
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);
 
773
                                }
 
774
                                else {
 
775
                                        IMB_exr_add_channel(exrhandle, rl->name, make_pass_name(rpass, a),
 
776
                                                            xstride, xstride * rr->rectx, rpass->rect + a);
 
777
                                }
753
778
                        }
754
779
                }
755
780
        }
757
782
        /* when the filename has no permissions, this can fail */
758
783
        if (IMB_exr_begin_write(exrhandle, filename, rr->rectx, rr->recty, compress)) {
759
784
                IMB_exr_write_channels(exrhandle);
760
 
                success= TRUE;
 
785
                success = TRUE;
761
786
        }
762
787
        else {
763
788
                /* TODO, get the error from openexr's exception */
764
 
                BKE_report(reports, RPT_ERROR, "Error Writing Render Result, see console");
765
 
                success= FALSE;
 
789
                BKE_report(reports, RPT_ERROR, "Error writing render result (see console)");
 
790
                success = FALSE;
766
791
        }
767
792
        IMB_exr_close(exrhandle);
768
793
 
778
803
        /* officially pushed result should be NULL... error can happen with do_seq */
779
804
        RE_FreeRenderResult(re->pushedresult);
780
805
        
781
 
        re->pushedresult= re->result;
782
 
        re->result= NULL;
 
806
        re->pushedresult = re->result;
 
807
        re->result = NULL;
783
808
}
784
809
 
785
810
/* if scemode is R_SINGLE_LAYER, at end of rendering, merge the both render results */
790
815
        RenderLayer *rl;
791
816
        int nr;
792
817
 
793
 
        if (re->result==NULL) {
 
818
        if (re->result == NULL) {
794
819
                printf("pop render result error; no current result!\n");
795
820
                return;
796
821
        }
798
823
        if (!re->pushedresult)
799
824
                return;
800
825
 
801
 
        if (re->pushedresult->rectx==re->result->rectx && re->pushedresult->recty==re->result->recty) {
 
826
        if (re->pushedresult->rectx == re->result->rectx && re->pushedresult->recty == re->result->recty) {
802
827
                /* find which layer in re->pushedresult should be replaced */
803
 
                rl= re->result->layers.first;
 
828
                rl = re->result->layers.first;
804
829
                
805
830
                /* render result should be empty after this */
806
831
                BLI_remlink(&re->result->layers, rl);
807
832
                
808
833
                /* reconstruct render result layers */
809
 
                for (nr=0, srl= re->scene->r.layers.first; srl; srl= srl->next, nr++) {
810
 
                        if (nr==re->r.actlay)
 
834
                for (nr = 0, srl = re->scene->r.layers.first; srl; srl = srl->next, nr++) {
 
835
                        if (nr == re->r.actlay) {
811
836
                                BLI_addtail(&re->result->layers, rl);
 
837
                        }
812
838
                        else {
813
 
                                rlpush= RE_GetRenderLayer(re->pushedresult, srl->name);
 
839
                                rlpush = RE_GetRenderLayer(re->pushedresult, srl->name);
814
840
                                if (rlpush) {
815
841
                                        BLI_remlink(&re->pushedresult->layers, rlpush);
816
842
                                        BLI_addtail(&re->result->layers, rlpush);
820
846
        }
821
847
 
822
848
        RE_FreeRenderResult(re->pushedresult);
823
 
        re->pushedresult= NULL;
 
849
        re->pushedresult = NULL;
824
850
}
825
851
 
826
852
/************************* EXR Tile File Rendering ***************************/
827
853
 
828
854
static void save_render_result_tile(RenderResult *rr, RenderResult *rrpart)
829
855
{
830
 
        RenderLayer *rlp;
 
856
        RenderLayer *rlp, *rl;
831
857
        RenderPass *rpassp;
832
858
        int offs, partx, party;
833
859
        
834
860
        BLI_lock_thread(LOCK_IMAGE);
835
861
        
836
 
        for (rlp= rrpart->layers.first; rlp; rlp= rlp->next) {
837
 
                
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);
 
864
 
 
865
                /* should never happen but prevents crash if it does */
 
866
                BLI_assert(rl);
 
867
                if (UNLIKELY(rl == NULL)) {
 
868
                        continue;
 
869
                }
 
870
 
 
871
                if (rrpart->crop) { /* filters add pixel extra */
 
872
                        offs = (rrpart->crop + rrpart->crop * rrpart->rectx);
840
873
                }
841
874
                else {
842
 
                        offs= 0;
 
875
                        offs = 0;
843
876
                }
844
877
                
845
878
                /* combined */
846
879
                if (rlp->rectf) {
847
 
                        int a, xstride= 4;
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);
 
880
                        int a, xstride = 4;
 
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);
 
884
                        }
851
885
                }
852
886
                
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);
 
893
                        }
859
894
                }
860
895
                
861
896
        }
862
897
 
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;
 
900
 
 
901
        for (rlp = rrpart->layers.first; rlp; rlp = rlp->next) {
 
902
                rl = RE_GetRenderLayer(rr, rlp->name);
 
903
 
 
904
                /* should never happen but prevents crash if it does */
 
905
                BLI_assert(rl);
 
906
                if (UNLIKELY(rl == NULL)) {
 
907
                        continue;
 
908
                }
 
909
 
 
910
                IMB_exrtile_write_channels(rl->exrhandle, partx, party, 0);
 
911
        }
866
912
 
867
913
        BLI_unlock_thread(LOCK_IMAGE);
868
914
}
871
917
{
872
918
        RenderPart *pa;
873
919
        RenderResult *rr;
 
920
        RenderLayer *rl;
874
921
        
875
 
        for (rr= re->result; rr; rr= rr->next) {
876
 
                IMB_exrtile_clear_channels(rr->exrhandle);
 
922
        for (rr = re->result; rr; rr = rr->next) {
 
923
                for (rl = rr->layers.first; rl; rl = rl->next) {
 
924
                        IMB_exrtile_clear_channels(rl->exrhandle);
877
925
                
878
 
                for (pa= re->parts.first; pa; pa= pa->next) {
879
 
                        if (pa->ready==0) {
880
 
                                int party= pa->disprect.ymin - re->disprect.ymin + pa->crop;
881
 
                                int partx= pa->disprect.xmin - re->disprect.xmin + pa->crop;
882
 
                                IMB_exrtile_write_channels(rr->exrhandle, partx, party, 0);
 
926
                        for (pa = re->parts.first; pa; pa = pa->next) {
 
927
                                if (pa->status != PART_STATUS_READY) {
 
928
                                        int party = pa->disprect.ymin - re->disprect.ymin + pa->crop;
 
929
                                        int partx = pa->disprect.xmin - re->disprect.xmin + pa->crop;
 
930
                                        IMB_exrtile_write_channels(rl->exrhandle, partx, party, 0);
 
931
                                }
883
932
                        }
884
933
                }
885
934
        }
889
938
void render_result_exr_file_begin(Render *re)
890
939
{
891
940
        RenderResult *rr;
 
941
        RenderLayer *rl;
892
942
        char str[FILE_MAX];
893
 
        
894
 
        for (rr= re->result; rr; rr= rr->next) {
895
 
                render_result_exr_file_path(re->scene, rr->sample_nr, str);
896
 
        
897
 
                printf("write exr tmp file, %dx%d, %s\n", rr->rectx, rr->recty, str);
898
 
                IMB_exrtile_begin_write(rr->exrhandle, str, 0, rr->rectx, rr->recty, re->partx, re->party);
 
943
 
 
944
        for (rr = re->result; rr; rr = rr->next) {
 
945
                for (rl = rr->layers.first; rl; rl = rl->next) {
 
946
                        render_result_exr_file_path(re->scene, rl->name, rr->sample_nr, str);
 
947
                        printf("write exr tmp file, %dx%d, %s\n", rr->rectx, rr->recty, str);
 
948
                        IMB_exrtile_begin_write(rl->exrhandle, str, 0, rr->rectx, rr->recty, re->partx, re->party);
 
949
                }
899
950
        }
900
951
}
901
952
 
903
954
void render_result_exr_file_end(Render *re)
904
955
{
905
956
        RenderResult *rr;
 
957
        RenderLayer *rl;
906
958
 
907
959
        save_empty_result_tiles(re);
908
960
        
909
 
        for (rr= re->result; rr; rr= rr->next) {
910
 
                IMB_exr_close(rr->exrhandle);
911
 
                rr->exrhandle= NULL;
 
961
        for (rr = re->result; rr; rr = rr->next) {
 
962
                for (rl = rr->layers.first; rl; rl = rl->next) {
 
963
                        IMB_exr_close(rl->exrhandle);
 
964
                        rl->exrhandle = NULL;
 
965
                }
 
966
 
 
967
                rr->do_exr_tile = FALSE;
912
968
        }
913
969
        
914
970
        render_result_free_list(&re->fullresult, re->result);
915
 
        re->result= NULL;
 
971
        re->result = NULL;
916
972
 
917
973
        render_result_exr_file_read(re, 0);
918
974
}
920
976
/* save part into exr file */
921
977
void render_result_exr_file_merge(RenderResult *rr, RenderResult *rrpart)
922
978
{
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);
925
981
}
926
982
 
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)
929
985
{
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];
931
987
        
932
988
        BLI_strncpy(di, G.main->name, FILE_MAX);
933
989
        BLI_splitdirstring(di, fi);
934
990
        
935
 
        if (sample==0)
936
 
                BLI_snprintf(name, sizeof(name), "%s_%s.exr", fi, scene->id.name+2);
 
991
        if (sample == 0)
 
992
                BLI_snprintf(name, sizeof(name), "%s_%s_%s.exr", fi, scene->id.name + 2, layname);
937
993
        else
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);
939
995
 
940
996
        BLI_make_file_string("/", filepath, BLI_temporary_dir(), name);
941
997
}
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)
945
1001
{
 
1002
        RenderLayer *rl;
946
1003
        char str[FILE_MAX];
947
 
        int success;
 
1004
        int success = TRUE;
948
1005
 
949
1006
        RE_FreeRenderResult(re->result);
950
 
        re->result= render_result_new(re, &re->disprect, 0, RR_USE_MEM);
951
 
 
952
 
        render_result_exr_file_path(re->scene, sample, str);
953
 
        printf("read exr tmp file: %s\n", str);
954
 
 
955
 
        if (render_result_exr_file_read_path(re->result, str)) {
956
 
                success= TRUE;
957
 
        }
958
 
        else {
959
 
                printf("cannot read: %s\n", str);
960
 
                success= FALSE;
961
 
 
 
1007
        re->result = render_result_new(re, &re->disprect, 0, RR_USE_MEM, RR_ALL_LAYERS);
 
1008
 
 
1009
        for (rl = re->result->layers.first; rl; rl = rl->next) {
 
1010
 
 
1011
                render_result_exr_file_path(re->scene, rl->name, sample, str);
 
1012
                printf("read exr tmp file: %s\n", str);
 
1013
 
 
1014
                if (!render_result_exr_file_read_path(re->result, rl, str)) {
 
1015
                        printf("cannot read: %s\n", str);
 
1016
                        success = FALSE;
 
1017
 
 
1018
                }
962
1019
        }
963
1020
 
964
1021
        return success;
965
1022
}
966
1023
 
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)
969
1026
{
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;
974
1031
 
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);
978
1035
                return 0;
979
1036
        }
980
1037
 
981
 
        if (rr == NULL || rectx!=rr->rectx || recty!=rr->recty) {
 
1038
        if (rr == NULL || rectx != rr->rectx || recty != rr->recty) {
982
1039
                if (rr)
983
1040
                        printf("error in reading render result: dimensions don't match\n");
984
1041
                else
987
1044
                return 0;
988
1045
        }
989
1046
 
990
 
        for (rl= rr->layers.first; rl; rl= rl->next) {
 
1047
        for (rl = rr->layers.first; rl; rl = rl->next) {
 
1048
                if (rl_single && rl_single != rl)
 
1049
                        continue;
 
1050
 
991
1051
                /* combined */
992
1052
                if (rl->rectf) {
993
 
                        int a, xstride= 4;
994
 
                        for (a=0; a<xstride; a++)
 
1053
                        int a, xstride = 4;
 
1054
                        for (a = 0; a < xstride; a++)
995
1055
                                IMB_exr_set_channel(exrhandle, rl->name, get_pass_name(SCE_PASS_COMBINED, a), 
996
 
                                                                        xstride, xstride*rectx, rl->rectf+a);
 
1056
                                                    xstride, xstride * rectx, rl->rectf + a);
997
1057
                }
998
1058
                
999
1059
                /* passes are allocated in sync */
1000
 
                for (rpass= rl->passes.first; rpass; rpass= rpass->next) {
1001
 
                        int a, xstride= rpass->channels;
1002
 
                        for (a=0; a<xstride; a++)
 
1060
                for (rpass = rl->passes.first; rpass; rpass = rpass->next) {
 
1061
                        int a, xstride = rpass->channels;
 
1062
                        for (a = 0; a < xstride; a++)
1003
1063
                                IMB_exr_set_channel(exrhandle, rl->name, get_pass_name(rpass->passtype, a), 
1004
 
                                                                        xstride, xstride*rectx, rpass->rect+a);
 
1064
                                                    xstride, xstride * rectx, rpass->rect + a);
1005
1065
 
1006
1066
                        BLI_strncpy(rpass->name, get_pass_name(rpass->passtype, -1), sizeof(rpass->name));
1007
1067
                }
1017
1077
 
1018
1078
ImBuf *render_result_rect_to_ibuf(RenderResult *rr, RenderData *rd)
1019
1079
{
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);
1022
1081
        
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;
1027
1086
        
1028
1087
        /* float factor for random dither, imbuf takes care of it */
1029
 
        ibuf->dither= rd->dither_intensity;
 
1088
        ibuf->dither = rd->dither_intensity;
1030
1089
        
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 */
1034
 
                if (ibuf->rect) {
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
 
1092
         */
 
1093
        if (ibuf->rect) {
 
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);
1038
1096
                }
1039
 
                else {
1040
 
                        ibuf->profile = IB_PROFILE_LINEAR_RGB;
 
1097
                else  {
 
1098
                        /* ensure no float buffer remained from previous frame */
 
1099
                        ibuf->rect_float = NULL;
1041
1100
                }
1042
1101
        }
1043
1102
 
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);
1050
 
                ibuf= ibuf_bw;
 
1109
                ibuf = ibuf_bw;
1051
1110
        }
1052
1111
 
1053
1112
        return ibuf;
1054
1113
}
1055
1114
 
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)
1057
1116
{
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);
1064
 
 
1065
1118
                if (!rr->rectf)
1066
 
                        rr->rectf= MEM_mallocN(4*sizeof(float)*rr->rectx*rr->recty, "render_seq rectf");
1067
 
                
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);
1071
 
                
 
1119
                        rr->rectf = MEM_mallocN(4 * sizeof(float) * rr->rectx * rr->recty, "render_seq rectf");
 
1120
                
 
1121
                memcpy(rr->rectf, ibuf->rect_float, 4 * sizeof(float) * rr->rectx * rr->recty);
 
1122
 
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);
1076
 
                        rr->rect32= NULL;
 
1127
                        rr->rect32 = NULL;
1077
1128
                }
1078
1129
        }
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");
1082
1133
 
1083
 
                memcpy(rr->rect32, ibuf->rect, 4*rr->rectx*rr->recty);
 
1134
                memcpy(rr->rect32, ibuf->rect, 4 * rr->rectx * rr->recty);
1084
1135
 
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);
1088
 
                        rr->rectf= NULL;
 
1139
                        rr->rectf = NULL;
1089
1140
                }
1090
1141
        }
1091
1142
}
1093
1144
void render_result_rect_fill_zero(RenderResult *rr)
1094
1145
{
1095
1146
        if (rr->rectf)
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);
1099
1150
        else
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");
1101
1152
}
1102
1153
 
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)
1104
1156
{
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);
1107
1159
        }
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);
1111
 
                int dither= 0;
1112
 
 
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);
1116
1163
        }
1117
1164
        else
1118
1165
                /* else fill with black */
1119
 
                memset(rect, 0, sizeof(int)*rectx*recty);
 
1166
                memset(rect, 0, sizeof(int) * rectx * recty);
1120
1167
}
1121
1168