Blender  V3.3
render_result.c
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-or-later
2  * Copyright 2006 Blender Foundation. All rights reserved. */
3 
8 #include <errno.h>
9 #include <stdio.h>
10 #include <stdlib.h>
11 #include <string.h>
12 
13 #include "MEM_guardedalloc.h"
14 
15 #include "BLI_ghash.h"
16 #include "BLI_hash_md5.h"
17 #include "BLI_listbase.h"
18 #include "BLI_path_util.h"
19 #include "BLI_rect.h"
20 #include "BLI_string.h"
21 #include "BLI_string_utils.h"
22 #include "BLI_threads.h"
23 #include "BLI_utildefines.h"
24 
25 #include "BKE_appdir.h"
26 #include "BKE_camera.h"
27 #include "BKE_global.h"
28 #include "BKE_image.h"
29 #include "BKE_image_format.h"
30 #include "BKE_image_save.h"
31 #include "BKE_report.h"
32 #include "BKE_scene.h"
33 
34 #include "IMB_colormanagement.h"
35 #include "IMB_imbuf.h"
36 #include "IMB_imbuf_types.h"
37 #include "IMB_openexr.h"
38 
39 #include "RE_engine.h"
40 
41 #include "render_result.h"
42 #include "render_types.h"
43 
44 /********************************** Free *************************************/
45 
47 {
48  while (rr->views.first) {
49  RenderView *rv = rr->views.first;
50  BLI_remlink(&rr->views, rv);
51 
52  if (rv->rect32) {
53  MEM_freeN(rv->rect32);
54  }
55 
56  if (rv->rectz) {
57  MEM_freeN(rv->rectz);
58  }
59 
60  if (rv->rectf) {
61  MEM_freeN(rv->rectf);
62  }
63 
64  MEM_freeN(rv);
65  }
66 
67  rr->have_combined = false;
68 }
69 
71 {
72  if (rr == NULL) {
73  return;
74  }
75 
76  while (rr->layers.first) {
77  RenderLayer *rl = rr->layers.first;
78 
79  while (rl->passes.first) {
80  RenderPass *rpass = rl->passes.first;
81  if (rpass->rect) {
82  MEM_freeN(rpass->rect);
83  }
84  BLI_remlink(&rl->passes, rpass);
85  MEM_freeN(rpass);
86  }
87  BLI_remlink(&rr->layers, rl);
88  MEM_freeN(rl);
89  }
90 
92 
93  if (rr->rect32) {
94  MEM_freeN(rr->rect32);
95  }
96  if (rr->rectz) {
97  MEM_freeN(rr->rectz);
98  }
99  if (rr->rectf) {
100  MEM_freeN(rr->rectf);
101  }
102  if (rr->text) {
103  MEM_freeN(rr->text);
104  }
105  if (rr->error) {
106  MEM_freeN(rr->error);
107  }
108 
110 
111  MEM_freeN(rr);
112 }
113 
115 {
116  RenderResult *rrnext;
117 
118  for (; rr; rr = rrnext) {
119  rrnext = rr->next;
120 
121  if (lb && lb->first) {
122  BLI_remlink(lb, rr);
123  }
124 
125  render_result_free(rr);
126  }
127 }
128 
129 /********************************* multiview *************************************/
130 
132 {
133  RenderView *rview;
134 
135  if (dst == NULL || src == NULL) {
136  return;
137  }
138 
139  for (rview = src->views.first; rview; rview = rview->next) {
140  RenderView *rv;
141 
142  rv = MEM_mallocN(sizeof(RenderView), "new render view");
143  BLI_addtail(&dst->views, rv);
144 
145  BLI_strncpy(rv->name, rview->name, sizeof(rv->name));
146  rv->rectf = rview->rectf;
147  rv->rectz = rview->rectz;
148  rv->rect32 = rview->rect32;
149  }
150 }
151 
153 {
154  if (rr == NULL) {
155  return;
156  }
157 
158  while (rr->views.first) {
159  RenderView *rv = rr->views.first;
160  BLI_remlink(&rr->views, rv);
161  MEM_freeN(rv);
162  }
163 }
164 
165 /********************************** New **************************************/
166 
168 {
169  if (rp->rect != NULL) {
170  return;
171  }
172 
173  const size_t rectsize = ((size_t)rr->rectx) * rr->recty * rp->channels;
174  rp->rect = MEM_callocN(sizeof(float) * rectsize, rp->name);
175 
176  if (STREQ(rp->name, RE_PASSNAME_VECTOR)) {
177  /* initialize to max speed */
178  float *rect = rp->rect;
179  for (int x = rectsize - 1; x >= 0; x--) {
180  rect[x] = PASS_VECTOR_MAX;
181  }
182  }
183  else if (STREQ(rp->name, RE_PASSNAME_Z)) {
184  float *rect = rp->rect;
185  for (int x = rectsize - 1; x >= 0; x--) {
186  rect[x] = 10e10;
187  }
188  }
189 }
190 
192  RenderLayer *rl,
193  int channels,
194  const char *name,
195  const char *viewname,
196  const char *chan_id,
197  const bool allocate)
198 {
199  const int view_id = BLI_findstringindex(&rr->views, viewname, offsetof(RenderView, name));
200  RenderPass *rpass = MEM_callocN(sizeof(RenderPass), name);
201 
202  rpass->channels = channels;
203  rpass->rectx = rl->rectx;
204  rpass->recty = rl->recty;
205  rpass->view_id = view_id;
206 
207  BLI_strncpy(rpass->name, name, sizeof(rpass->name));
208  BLI_strncpy(rpass->chan_id, chan_id, sizeof(rpass->chan_id));
209  BLI_strncpy(rpass->view, viewname, sizeof(rpass->view));
211  rpass->fullname, NULL, rpass->name, rpass->view, rpass->chan_id, -1);
212 
213  if (rl->exrhandle) {
214  int a;
215  for (a = 0; a < channels; a++) {
216  char passname[EXR_PASS_MAXNAME];
217  RE_render_result_full_channel_name(passname, NULL, rpass->name, NULL, rpass->chan_id, a);
218  IMB_exr_add_channel(rl->exrhandle, rl->name, passname, viewname, 0, 0, NULL, false);
219  }
220  }
221 
222  BLI_addtail(&rl->passes, rpass);
223 
224  if (allocate) {
225  render_layer_allocate_pass(rr, rpass);
226  }
227  else {
228  /* The result contains non-allocated pass now, so tag it as such. */
229  rr->passes_allocated = false;
230  }
231 
232  return rpass;
233 }
234 
236  rcti *partrct,
237  const char *layername,
238  const char *viewname)
239 {
240  RenderResult *rr;
241  RenderLayer *rl;
242  RenderView *rv;
243  int rectx, recty;
244 
245  rectx = BLI_rcti_size_x(partrct);
246  recty = BLI_rcti_size_y(partrct);
247 
248  if (rectx <= 0 || recty <= 0) {
249  return NULL;
250  }
251 
252  rr = MEM_callocN(sizeof(RenderResult), "new render result");
253  rr->rectx = rectx;
254  rr->recty = recty;
255  rr->renrect.xmin = 0;
256  rr->renrect.xmax = rectx;
257 
258  /* tilerect is relative coordinates within render disprect. do not subtract crop yet */
259  rr->tilerect.xmin = partrct->xmin - re->disprect.xmin;
260  rr->tilerect.xmax = partrct->xmax - re->disprect.xmin;
261  rr->tilerect.ymin = partrct->ymin - re->disprect.ymin;
262  rr->tilerect.ymax = partrct->ymax - re->disprect.ymin;
263 
264  rr->passes_allocated = false;
265 
266  render_result_views_new(rr, &re->r);
267 
268  /* check renderdata for amount of layers */
269  FOREACH_VIEW_LAYER_TO_RENDER_BEGIN (re, view_layer) {
270  if (layername && layername[0]) {
271  if (!STREQ(view_layer->name, layername)) {
272  continue;
273  }
274  }
275 
276  rl = MEM_callocN(sizeof(RenderLayer), "new render layer");
277  BLI_addtail(&rr->layers, rl);
278 
279  BLI_strncpy(rl->name, view_layer->name, sizeof(rl->name));
280  rl->layflag = view_layer->layflag;
281 
282  rl->passflag = view_layer->passflag;
283 
284  rl->rectx = rectx;
285  rl->recty = recty;
286 
287  for (rv = rr->views.first; rv; rv = rv->next) {
288  const char *view = rv->name;
289 
290  if (viewname && viewname[0]) {
291  if (!STREQ(view, viewname)) {
292  continue;
293  }
294  }
295 
296 #define RENDER_LAYER_ADD_PASS_SAFE(rr, rl, channels, name, viewname, chan_id) \
297  do { \
298  if (render_layer_add_pass(rr, rl, channels, name, viewname, chan_id, false) == NULL) { \
299  render_result_free(rr); \
300  return NULL; \
301  } \
302  } while (false)
303 
304  /* A render-layer should always have a "Combined" pass. */
305  render_layer_add_pass(rr, rl, 4, "Combined", view, "RGBA", false);
306 
307  if (view_layer->passflag & SCE_PASS_Z) {
309  }
310  if (view_layer->passflag & SCE_PASS_VECTOR) {
312  }
313  if (view_layer->passflag & SCE_PASS_NORMAL) {
315  }
316  if (view_layer->passflag & SCE_PASS_POSITION) {
318  }
319  if (view_layer->passflag & SCE_PASS_UV) {
320  RENDER_LAYER_ADD_PASS_SAFE(rr, rl, 3, RE_PASSNAME_UV, view, "UVA");
321  }
322  if (view_layer->passflag & SCE_PASS_EMIT) {
324  }
325  if (view_layer->passflag & SCE_PASS_AO) {
326  RENDER_LAYER_ADD_PASS_SAFE(rr, rl, 3, RE_PASSNAME_AO, view, "RGB");
327  }
328  if (view_layer->passflag & SCE_PASS_ENVIRONMENT) {
330  }
331  if (view_layer->passflag & SCE_PASS_SHADOW) {
333  }
334  if (view_layer->passflag & SCE_PASS_INDEXOB) {
336  }
337  if (view_layer->passflag & SCE_PASS_INDEXMA) {
339  }
340  if (view_layer->passflag & SCE_PASS_MIST) {
342  }
343  if (view_layer->passflag & SCE_PASS_DIFFUSE_DIRECT) {
345  }
346  if (view_layer->passflag & SCE_PASS_DIFFUSE_INDIRECT) {
348  }
349  if (view_layer->passflag & SCE_PASS_DIFFUSE_COLOR) {
351  }
352  if (view_layer->passflag & SCE_PASS_GLOSSY_DIRECT) {
354  }
355  if (view_layer->passflag & SCE_PASS_GLOSSY_INDIRECT) {
357  }
358  if (view_layer->passflag & SCE_PASS_GLOSSY_COLOR) {
360  }
361  if (view_layer->passflag & SCE_PASS_TRANSM_DIRECT) {
363  }
364  if (view_layer->passflag & SCE_PASS_TRANSM_INDIRECT) {
366  }
367  if (view_layer->passflag & SCE_PASS_TRANSM_COLOR) {
369  }
370  if (view_layer->passflag & SCE_PASS_SUBSURFACE_DIRECT) {
372  }
373  if (view_layer->passflag & SCE_PASS_SUBSURFACE_INDIRECT) {
375  }
376  if (view_layer->passflag & SCE_PASS_SUBSURFACE_COLOR) {
378  }
379 #undef RENDER_LAYER_ADD_PASS_SAFE
380  }
381  }
383 
384  /* Preview-render doesn't do layers, so we make a default one. */
385  if (BLI_listbase_is_empty(&rr->layers) && !(layername && layername[0])) {
386  rl = MEM_callocN(sizeof(RenderLayer), "new render layer");
387  BLI_addtail(&rr->layers, rl);
388 
389  rl->rectx = rectx;
390  rl->recty = recty;
391 
392  for (rv = rr->views.first; rv; rv = rv->next) {
393  const char *view = rv->name;
394 
395  if (viewname && viewname[0]) {
396  if (!STREQ(view, viewname)) {
397  continue;
398  }
399  }
400 
401  /* A render-layer should always have a "Combined" pass. */
402  render_layer_add_pass(rr, rl, 4, RE_PASSNAME_COMBINED, view, "RGBA", false);
403  }
404 
405  /* NOTE: this has to be in sync with `scene.cc`. */
408 
409  re->active_view_layer = 0;
410  }
411 
412  /* Border render; calculate offset for use in compositor. compo is centralized coords. */
413  /* XXX(ton): obsolete? I now use it for drawing border render offset. */
414  rr->xof = re->disprect.xmin + BLI_rcti_cent_x(&re->disprect) - (re->winx / 2);
415  rr->yof = re->disprect.ymin + BLI_rcti_cent_y(&re->disprect) - (re->winy / 2);
416 
417  /* Preview does not support deferred render result allocation. */
418  if (re->r.scemode & R_BUTS_PREVIEW) {
420  }
421 
422  return rr;
423 }
424 
426 {
427  if (rr == NULL) {
428  /* Happens when the result was not yet allocated for the current scene or slot configuration.
429  */
430  return;
431  }
432 
433  LISTBASE_FOREACH (RenderLayer *, rl, &rr->layers) {
434  LISTBASE_FOREACH (RenderPass *, rp, &rl->passes) {
435  if (rl->exrhandle != NULL && !STREQ(rp->name, RE_PASSNAME_COMBINED)) {
436  continue;
437  }
438 
440  }
441  }
442 
443  rr->passes_allocated = true;
444 }
445 
446 void render_result_clone_passes(Render *re, RenderResult *rr, const char *viewname)
447 {
448  RenderLayer *rl;
449  RenderPass *main_rp;
450 
451  for (rl = rr->layers.first; rl; rl = rl->next) {
452  RenderLayer *main_rl = BLI_findstring(
453  &re->result->layers, rl->name, offsetof(RenderLayer, name));
454  if (!main_rl) {
455  continue;
456  }
457 
458  for (main_rp = main_rl->passes.first; main_rp; main_rp = main_rp->next) {
459  if (viewname && viewname[0] && !STREQ(main_rp->view, viewname)) {
460  continue;
461  }
462 
463  /* Compare fullname to make sure that the view also is equal. */
465  &rl->passes, main_rp->fullname, offsetof(RenderPass, fullname));
466  if (!rp) {
468  rr, rl, main_rp->channels, main_rp->name, main_rp->view, main_rp->chan_id, false);
469  }
470  }
471  }
472 }
473 
475  const char *name,
476  int channels,
477  const char *chan_id,
478  const char *layername,
479  const char *viewname,
480  const bool allocate)
481 {
482  RenderLayer *rl;
483  RenderPass *rp;
484  RenderView *rv;
485 
486  for (rl = rr->layers.first; rl; rl = rl->next) {
487  if (layername && layername[0] && !STREQ(rl->name, layername)) {
488  continue;
489  }
490 
491  for (rv = rr->views.first; rv; rv = rv->next) {
492  const char *view = rv->name;
493 
494  if (viewname && viewname[0] && !STREQ(view, viewname)) {
495  continue;
496  }
497 
498  /* Ensure that the pass doesn't exist yet. */
499  for (rp = rl->passes.first; rp; rp = rp->next) {
500  if (!STREQ(rp->name, name)) {
501  continue;
502  }
503  if (!STREQ(rp->view, view)) {
504  continue;
505  }
506  break;
507  }
508 
509  if (!rp) {
510  render_layer_add_pass(rr, rl, channels, name, view, chan_id, allocate);
511  }
512  }
513  }
514 }
515 
517  const char *layname,
518  const char *passname,
519  const char *viewname,
520  const char *chan_id,
521  const int channel)
522 {
523  /* OpenEXR compatible full channel name. */
524  const char *strings[4];
525  int strings_len = 0;
526 
527  if (layname && layname[0]) {
528  strings[strings_len++] = layname;
529  }
530  if (passname && passname[0]) {
531  strings[strings_len++] = passname;
532  }
533  if (viewname && viewname[0]) {
534  strings[strings_len++] = viewname;
535  }
536 
537  char token[2];
538  if (channel >= 0) {
539  ARRAY_SET_ITEMS(token, chan_id[channel], '\0');
540  strings[strings_len++] = token;
541  }
542 
543  BLI_string_join_array_by_sep_char(fullname, EXR_PASS_MAXNAME, '.', strings, strings_len);
544 }
545 
546 static int passtype_from_name(const char *name)
547 {
548  const char delim[] = {'.', '\0'};
549  const char *sep, *suf;
550  int len = BLI_str_partition(name, delim, &sep, &suf);
551 
552 #define CHECK_PASS(NAME) \
553  if (STREQLEN(name, RE_PASSNAME_##NAME, len)) { \
554  return SCE_PASS_##NAME; \
555  } \
556  ((void)0)
557 
558  CHECK_PASS(COMBINED);
559  CHECK_PASS(Z);
560  CHECK_PASS(VECTOR);
562  CHECK_PASS(UV);
563  CHECK_PASS(EMIT);
564  CHECK_PASS(SHADOW);
565  CHECK_PASS(AO);
566  CHECK_PASS(ENVIRONMENT);
567  CHECK_PASS(INDEXOB);
568  CHECK_PASS(INDEXMA);
569  CHECK_PASS(MIST);
570  CHECK_PASS(DIFFUSE_DIRECT);
571  CHECK_PASS(DIFFUSE_INDIRECT);
572  CHECK_PASS(DIFFUSE_COLOR);
573  CHECK_PASS(GLOSSY_DIRECT);
574  CHECK_PASS(GLOSSY_INDIRECT);
575  CHECK_PASS(GLOSSY_COLOR);
576  CHECK_PASS(TRANSM_DIRECT);
577  CHECK_PASS(TRANSM_INDIRECT);
578  CHECK_PASS(TRANSM_COLOR);
579  CHECK_PASS(SUBSURFACE_DIRECT);
580  CHECK_PASS(SUBSURFACE_INDIRECT);
581  CHECK_PASS(SUBSURFACE_COLOR);
582 
583 #undef CHECK_PASS
584  return 0;
585 }
586 
587 /* callbacks for render_result_new_from_exr */
588 static void *ml_addlayer_cb(void *base, const char *str)
589 {
590  RenderResult *rr = base;
591  RenderLayer *rl;
592 
593  rl = MEM_callocN(sizeof(RenderLayer), "new render layer");
594  BLI_addtail(&rr->layers, rl);
595 
597  return rl;
598 }
599 
600 static void ml_addpass_cb(void *base,
601  void *lay,
602  const char *name,
603  float *rect,
604  int totchan,
605  const char *chan_id,
606  const char *view)
607 {
608  RenderResult *rr = base;
609  RenderLayer *rl = lay;
610  RenderPass *rpass = MEM_callocN(sizeof(RenderPass), "loaded pass");
611 
612  BLI_addtail(&rl->passes, rpass);
613  rpass->channels = totchan;
614  rl->passflag |= passtype_from_name(name);
615 
616  /* channel id chars */
617  BLI_strncpy(rpass->chan_id, chan_id, sizeof(rpass->chan_id));
618 
619  rpass->rect = rect;
620  BLI_strncpy(rpass->name, name, EXR_PASS_MAXNAME);
621  BLI_strncpy(rpass->view, view, sizeof(rpass->view));
622  RE_render_result_full_channel_name(rpass->fullname, NULL, name, view, rpass->chan_id, -1);
623 
624  if (view[0] != '\0') {
625  rpass->view_id = BLI_findstringindex(&rr->views, view, offsetof(RenderView, name));
626  }
627  else {
628  rpass->view_id = 0;
629  }
630 }
631 
632 static void *ml_addview_cb(void *base, const char *str)
633 {
634  RenderResult *rr = base;
635  RenderView *rv;
636 
637  rv = MEM_callocN(sizeof(RenderView), "new render view");
639 
640  /* For stereo drawing we need to ensure:
641  * STEREO_LEFT_NAME == STEREO_LEFT_ID and
642  * STEREO_RIGHT_NAME == STEREO_RIGHT_ID */
643 
644  if (STREQ(str, STEREO_LEFT_NAME)) {
645  BLI_addhead(&rr->views, rv);
646  }
647  else if (STREQ(str, STEREO_RIGHT_NAME)) {
648  RenderView *left_rv = BLI_findstring(&rr->views, STEREO_LEFT_NAME, offsetof(RenderView, name));
649 
650  if (left_rv == NULL) {
651  BLI_addhead(&rr->views, rv);
652  }
653  else {
654  BLI_insertlinkafter(&rr->views, left_rv, rv);
655  }
656  }
657  else {
658  BLI_addtail(&rr->views, rv);
659  }
660 
661  return rv;
662 }
663 
664 static int order_render_passes(const void *a, const void *b)
665 {
666  /* 1 if `a` is after `b`. */
667  RenderPass *rpa = (RenderPass *)a;
668  RenderPass *rpb = (RenderPass *)b;
669  unsigned int passtype_a = passtype_from_name(rpa->name);
670  unsigned int passtype_b = passtype_from_name(rpb->name);
671 
672  /* Render passes with default type always go first. */
673  if (passtype_b && !passtype_a) {
674  return 1;
675  }
676  if (passtype_a && !passtype_b) {
677  return 0;
678  }
679 
680  if (passtype_a && passtype_b) {
681  if (passtype_a > passtype_b) {
682  return 1;
683  }
684  if (passtype_a < passtype_b) {
685  return 0;
686  }
687  }
688  else {
689  int cmp = strncmp(rpa->name, rpb->name, EXR_PASS_MAXNAME);
690  if (cmp > 0) {
691  return 1;
692  }
693  if (cmp < 0) {
694  return 0;
695  }
696  }
697 
698  /* they have the same type */
699  /* left first */
700  if (STREQ(rpa->view, STEREO_LEFT_NAME)) {
701  return 0;
702  }
703  if (STREQ(rpb->view, STEREO_LEFT_NAME)) {
704  return 1;
705  }
706 
707  /* right second */
708  if (STREQ(rpa->view, STEREO_RIGHT_NAME)) {
709  return 0;
710  }
711  if (STREQ(rpb->view, STEREO_RIGHT_NAME)) {
712  return 1;
713  }
714 
715  /* remaining in ascending id order */
716  return (rpa->view_id < rpb->view_id);
717 }
718 
720  void *exrhandle, const char *colorspace, bool predivide, int rectx, int recty)
721 {
722  RenderResult *rr = MEM_callocN(sizeof(RenderResult), __func__);
723  RenderLayer *rl;
724  RenderPass *rpass;
725  const char *to_colorspace = IMB_colormanagement_role_colorspace_name_get(
727 
728  rr->rectx = rectx;
729  rr->recty = recty;
730 
732 
733  for (rl = rr->layers.first; rl; rl = rl->next) {
734  rl->rectx = rectx;
735  rl->recty = recty;
736 
738 
739  for (rpass = rl->passes.first; rpass; rpass = rpass->next) {
740  rpass->rectx = rectx;
741  rpass->recty = recty;
742 
743  if (rpass->channels >= 3) {
745  rpass->rectx,
746  rpass->recty,
747  rpass->channels,
748  colorspace,
749  to_colorspace,
750  predivide);
751  }
752  }
753  }
754 
755  return rr;
756 }
757 
758 void render_result_view_new(RenderResult *rr, const char *viewname)
759 {
760  RenderView *rv = MEM_callocN(sizeof(RenderView), "new render view");
761  BLI_addtail(&rr->views, rv);
762  BLI_strncpy(rv->name, viewname, sizeof(rv->name));
763 }
764 
766 {
767  SceneRenderView *srv;
768 
769  /* clear previously existing views - for sequencer */
771 
772  /* check renderdata for amount of views */
773  if (rd->scemode & R_MULTIVIEW) {
774  for (srv = rd->views.first; srv; srv = srv->next) {
775  if (BKE_scene_multiview_is_render_view_active(rd, srv) == false) {
776  continue;
777  }
778  render_result_view_new(rr, srv->name);
779  }
780  }
781 
782  /* we always need at least one view */
783  if (BLI_listbase_count_at_most(&rr->views, 1) == 0) {
784  render_result_view_new(rr, "");
785  }
786 }
787 
788 /*********************************** Merge ***********************************/
789 
790 static void do_merge_tile(
791  RenderResult *rr, RenderResult *rrpart, float *target, float *tile, int pixsize)
792 {
793  int y, tilex, tiley;
794  size_t ofs, copylen;
795 
796  copylen = tilex = rrpart->rectx;
797  tiley = rrpart->recty;
798 
799  ofs = (((size_t)rrpart->tilerect.ymin) * rr->rectx + rrpart->tilerect.xmin);
800  target += pixsize * ofs;
801 
802  copylen *= sizeof(float) * pixsize;
803  tilex *= pixsize;
804  ofs = pixsize * rr->rectx;
805 
806  for (y = 0; y < tiley; y++) {
807  memcpy(target, tile, copylen);
808  target += ofs;
809  tile += tilex;
810  }
811 }
812 
814 {
815  RenderLayer *rl, *rlp;
816  RenderPass *rpass, *rpassp;
817 
818  for (rl = rr->layers.first; rl; rl = rl->next) {
819  rlp = RE_GetRenderLayer(rrpart, rl->name);
820  if (rlp) {
821  /* Passes are allocated in sync. */
822  for (rpass = rl->passes.first, rpassp = rlp->passes.first; rpass && rpassp;
823  rpass = rpass->next) {
824  /* For save buffers, skip any passes that are only saved to disk. */
825  if (rpass->rect == NULL || rpassp->rect == NULL) {
826  continue;
827  }
828  /* Render-result have all passes, render-part only the active view's passes. */
829  if (!STREQ(rpassp->fullname, rpass->fullname)) {
830  continue;
831  }
832 
833  do_merge_tile(rr, rrpart, rpass->rect, rpassp->rect, rpass->channels);
834 
835  /* manually get next render pass */
836  rpassp = rpassp->next;
837  }
838  }
839  }
840 }
841 
842 /**************************** Single Layer Rendering *************************/
843 
845 {
846  /* all layers except the active one get temporally pushed away */
847 
848  /* officially pushed result should be NULL... error can happen with do_seq */
850 
851  re->pushedresult = re->result;
852  re->result = NULL;
853 }
854 
856 {
857  ViewLayer *view_layer;
858  RenderLayer *rlpush;
859  RenderLayer *rl;
860  int nr;
861 
862  if (re->result == NULL) {
863  printf("pop render result error; no current result!\n");
864  return;
865  }
866 
867  if (!re->pushedresult) {
868  return;
869  }
870 
871  if (re->pushedresult->rectx == re->result->rectx &&
872  re->pushedresult->recty == re->result->recty) {
873  /* find which layer in re->pushedresult should be replaced */
874  rl = re->result->layers.first;
875 
876  /* render result should be empty after this */
877  BLI_remlink(&re->result->layers, rl);
878 
879  /* reconstruct render result layers */
880  for (nr = 0, view_layer = re->view_layers.first; view_layer;
881  view_layer = view_layer->next, nr++) {
882  if (nr == re->active_view_layer) {
883  BLI_addtail(&re->result->layers, rl);
884  }
885  else {
886  rlpush = RE_GetRenderLayer(re->pushedresult, view_layer->name);
887  if (rlpush) {
888  BLI_remlink(&re->pushedresult->layers, rlpush);
889  BLI_addtail(&re->result->layers, rlpush);
890  }
891  }
892  }
893  }
894 
896  re->pushedresult = NULL;
897 }
898 
900  RenderLayer *rl_single,
901  const char *filepath)
902 {
903  RenderLayer *rl;
904  RenderPass *rpass;
905  void *exrhandle = IMB_exr_get_handle();
906  int rectx, recty;
907 
908  if (!IMB_exr_begin_read(exrhandle, filepath, &rectx, &recty, false)) {
909  printf("failed being read %s\n", filepath);
910  IMB_exr_close(exrhandle);
911  return 0;
912  }
913 
914  if (rr == NULL || rectx != rr->rectx || recty != rr->recty) {
915  if (rr) {
916  printf("error in reading render result: dimensions don't match\n");
917  }
918  else {
919  printf("error in reading render result: NULL result pointer\n");
920  }
921  IMB_exr_close(exrhandle);
922  return 0;
923  }
924 
925  for (rl = rr->layers.first; rl; rl = rl->next) {
926  if (rl_single && rl_single != rl) {
927  continue;
928  }
929 
930  /* passes are allocated in sync */
931  for (rpass = rl->passes.first; rpass; rpass = rpass->next) {
932  const int xstride = rpass->channels;
933  int a;
934  char fullname[EXR_PASS_MAXNAME];
935 
936  for (a = 0; a < xstride; a++) {
938  fullname, NULL, rpass->name, rpass->view, rpass->chan_id, a);
940  exrhandle, rl->name, fullname, xstride, xstride * rectx, rpass->rect + a);
941  }
942 
944  rpass->fullname, NULL, rpass->name, rpass->view, rpass->chan_id, -1);
945  }
946  }
947 
948  IMB_exr_read_channels(exrhandle);
949  IMB_exr_close(exrhandle);
950 
951  return 1;
952 }
953 
954 static void render_result_exr_file_cache_path(Scene *sce, const char *root, char *r_path)
955 {
956  char filename_full[FILE_MAX + MAX_ID_NAME + 100], filename[FILE_MAXFILE], dirname[FILE_MAXDIR];
957  char path_digest[16] = {0};
958  char path_hexdigest[33];
959 
960  /* If root is relative, use either current .blend file dir, or temp one if not saved. */
961  const char *blendfile_path = BKE_main_blendfile_path_from_global();
962  if (blendfile_path[0] != '\0') {
963  BLI_split_dirfile(blendfile_path, dirname, filename, sizeof(dirname), sizeof(filename));
964  BLI_path_extension_replace(filename, sizeof(filename), ""); /* strip '.blend' */
965  BLI_hash_md5_buffer(blendfile_path, strlen(blendfile_path), path_digest);
966  }
967  else {
969  BLI_strncpy(filename, "UNSAVED", sizeof(filename));
970  }
971  BLI_hash_md5_to_hexdigest(path_digest, path_hexdigest);
972 
973  /* Default to *non-volatile* tmp dir. */
974  if (*root == '\0') {
975  root = BKE_tempdir_base();
976  }
977 
978  BLI_snprintf(filename_full,
979  sizeof(filename_full),
980  "cached_RR_%s_%s_%s.exr",
981  filename,
982  sce->id.name + 2,
983  path_hexdigest);
984  BLI_make_file_string(dirname, r_path, root, filename_full);
985 }
986 
988 {
989  RenderResult *rr = re->result;
990  char str[FILE_MAXFILE + FILE_MAXFILE + MAX_ID_NAME + 100];
991  char *root = U.render_cachedir;
992 
994 
996  printf("Caching exr file, %dx%d, %s\n", rr->rectx, rr->recty, str);
997 
998  BKE_image_render_write_exr(NULL, rr, str, NULL, true, NULL, -1);
999 }
1000 
1002 {
1003  /* File path to cache. */
1004  char filepath[FILE_MAXFILE + MAX_ID_NAME + MAX_ID_NAME + 100] = "";
1005  char *root = U.render_cachedir;
1006  render_result_exr_file_cache_path(re->scene, root, filepath);
1007 
1008  printf("read exr cache file: %s\n", filepath);
1009 
1010  /* Try opening the file. */
1011  void *exrhandle = IMB_exr_get_handle();
1012  int rectx, recty;
1013 
1014  if (!IMB_exr_begin_read(exrhandle, filepath, &rectx, &recty, true)) {
1015  printf("cannot read: %s\n", filepath);
1016  IMB_exr_close(exrhandle);
1017  return false;
1018  }
1019 
1020  /* Read file contents into render result. */
1023 
1024  IMB_exr_read_channels(exrhandle);
1025  re->result = render_result_new_from_exr(exrhandle, colorspace, false, rectx, recty);
1026 
1027  IMB_exr_close(exrhandle);
1028 
1029  return true;
1030 }
1031 
1032 /*************************** Combined Pixel Rect *****************************/
1033 
1035  const ImageFormatData *imf,
1036  const float dither,
1037  const int view_id)
1038 {
1039  ImBuf *ibuf = IMB_allocImBuf(rr->rectx, rr->recty, imf->planes, 0);
1040  RenderView *rv = RE_RenderViewGetById(rr, view_id);
1041 
1042  /* if not exists, BKE_imbuf_write makes one */
1043  ibuf->rect = (unsigned int *)rv->rect32;
1044  ibuf->rect_float = rv->rectf;
1045  ibuf->zbuf_float = rv->rectz;
1046 
1047  /* float factor for random dither, imbuf takes care of it */
1048  ibuf->dither = dither;
1049 
1050  /* prepare to gamma correct to sRGB color space
1051  * note that sequence editor can generate 8bpc render buffers
1052  */
1053  if (ibuf->rect) {
1054  if (BKE_imtype_valid_depths(imf->imtype) &
1056  if (imf->depth == R_IMF_CHAN_DEPTH_8) {
1057  /* Higher depth bits are supported but not needed for current file output. */
1058  ibuf->rect_float = NULL;
1059  }
1060  else {
1061  IMB_float_from_rect(ibuf);
1062  }
1063  }
1064  else {
1065  /* ensure no float buffer remained from previous frame */
1066  ibuf->rect_float = NULL;
1067  }
1068  }
1069 
1070  /* Color -> gray-scale. */
1071  /* editing directly would alter the render view */
1072  if (imf->planes == R_IMF_PLANES_BW) {
1073  ImBuf *ibuf_bw = IMB_dupImBuf(ibuf);
1074  IMB_color_to_bw(ibuf_bw);
1075  IMB_freeImBuf(ibuf);
1076  ibuf = ibuf_bw;
1077  }
1078 
1079  return ibuf;
1080 }
1081 
1082 void RE_render_result_rect_from_ibuf(RenderResult *rr, const ImBuf *ibuf, const int view_id)
1083 {
1084  RenderView *rv = RE_RenderViewGetById(rr, view_id);
1085 
1086  if (ibuf->rect_float) {
1087  rr->have_combined = true;
1088 
1089  if (!rv->rectf) {
1090  rv->rectf = MEM_mallocN(sizeof(float[4]) * rr->rectx * rr->recty, "render_seq rectf");
1091  }
1092 
1093  memcpy(rv->rectf, ibuf->rect_float, sizeof(float[4]) * rr->rectx * rr->recty);
1094 
1095  /* TSK! Since sequence render doesn't free the *rr render result, the old rect32
1096  * can hang around when sequence render has rendered a 32 bits one before */
1097  MEM_SAFE_FREE(rv->rect32);
1098  }
1099  else if (ibuf->rect) {
1100  rr->have_combined = true;
1101 
1102  if (!rv->rect32) {
1103  rv->rect32 = MEM_mallocN(sizeof(int) * rr->rectx * rr->recty, "render_seq rect");
1104  }
1105 
1106  memcpy(rv->rect32, ibuf->rect, 4 * rr->rectx * rr->recty);
1107 
1108  /* Same things as above, old rectf can hang around from previous render. */
1109  MEM_SAFE_FREE(rv->rectf);
1110  }
1111 }
1112 
1113 void render_result_rect_fill_zero(RenderResult *rr, const int view_id)
1114 {
1115  RenderView *rv = RE_RenderViewGetById(rr, view_id);
1116 
1117  if (rv->rectf) {
1118  memset(rv->rectf, 0, sizeof(float[4]) * rr->rectx * rr->recty);
1119  }
1120  else if (rv->rect32) {
1121  memset(rv->rect32, 0, 4 * rr->rectx * rr->recty);
1122  }
1123  else {
1124  rv->rect32 = MEM_callocN(sizeof(int) * rr->rectx * rr->recty, "render_seq rect");
1125  }
1126 }
1127 
1129  unsigned int *rect,
1130  int rectx,
1131  int recty,
1132  const ColorManagedViewSettings *view_settings,
1133  const ColorManagedDisplaySettings *display_settings,
1134  const int view_id)
1135 {
1136  RenderView *rv = RE_RenderViewGetById(rr, view_id);
1137 
1138  if (rv && rv->rect32) {
1139  memcpy(rect, rv->rect32, sizeof(int) * rr->rectx * rr->recty);
1140  }
1141  else if (rv && rv->rectf) {
1142  IMB_display_buffer_transform_apply((unsigned char *)rect,
1143  rv->rectf,
1144  rr->rectx,
1145  rr->recty,
1146  4,
1147  view_settings,
1148  display_settings,
1149  true);
1150  }
1151  else {
1152  /* else fill with black */
1153  memset(rect, 0, sizeof(int) * rectx * recty);
1154  }
1155 }
1156 
1157 /*************************** multiview functions *****************************/
1158 
1160 {
1161  if (rr == NULL) {
1162  return false;
1163  }
1164 
1165  const RenderView *rv = rr->views.first;
1166  if (rv == NULL) {
1167  return false;
1168  }
1169 
1170  return (rv->rect32 || rv->rectf);
1171 }
1172 
1174 {
1175  for (const RenderView *rview = rr->views.first; rview; rview = rview->next) {
1176  if (rview->rect32 && !rview->rectf) {
1177  return false;
1178  }
1179  }
1180 
1181  return true;
1182 }
1183 
1185 {
1186  if (!BLI_findstring(&rr->views, STEREO_LEFT_NAME, offsetof(RenderView, name))) {
1187  return false;
1188  }
1189 
1190  if (!BLI_findstring(&rr->views, STEREO_RIGHT_NAME, offsetof(RenderView, name))) {
1191  return false;
1192  }
1193 
1194  return true;
1195 }
1196 
1198 {
1199  RenderView *rv = BLI_findlink(&rr->views, view_id);
1200  BLI_assert(rr->views.first);
1201  return rv ? rv : rr->views.first;
1202 }
1203 
1205 {
1206  RenderView *rv = BLI_findstring(&rr->views, viewname, offsetof(RenderView, name));
1207  BLI_assert(rr->views.first);
1208  return rv ? rv : rr->views.first;
1209 }
1210 
1212 {
1213  RenderPass *new_rpass = MEM_mallocN(sizeof(RenderPass), "new render pass");
1214  *new_rpass = *rpass;
1215  new_rpass->next = new_rpass->prev = NULL;
1216  if (new_rpass->rect != NULL) {
1217  new_rpass->rect = MEM_dupallocN(new_rpass->rect);
1218  }
1219  return new_rpass;
1220 }
1221 
1223 {
1224  RenderLayer *new_rl = MEM_mallocN(sizeof(RenderLayer), "new render layer");
1225  *new_rl = *rl;
1226  new_rl->next = new_rl->prev = NULL;
1227  new_rl->passes.first = new_rl->passes.last = NULL;
1228  new_rl->exrhandle = NULL;
1229  for (RenderPass *rpass = rl->passes.first; rpass != NULL; rpass = rpass->next) {
1230  RenderPass *new_rpass = duplicate_render_pass(rpass);
1231  BLI_addtail(&new_rl->passes, new_rpass);
1232  }
1233  return new_rl;
1234 }
1235 
1237 {
1238  RenderView *new_rview = MEM_mallocN(sizeof(RenderView), "new render view");
1239  *new_rview = *rview;
1240  if (new_rview->rectf != NULL) {
1241  new_rview->rectf = MEM_dupallocN(new_rview->rectf);
1242  }
1243  if (new_rview->rectz != NULL) {
1244  new_rview->rectz = MEM_dupallocN(new_rview->rectz);
1245  }
1246  if (new_rview->rect32 != NULL) {
1247  new_rview->rect32 = MEM_dupallocN(new_rview->rect32);
1248  }
1249  return new_rview;
1250 }
1251 
1253 {
1254  RenderResult *new_rr = MEM_mallocN(sizeof(RenderResult), "new duplicated render result");
1255  *new_rr = *rr;
1256  new_rr->next = new_rr->prev = NULL;
1257  new_rr->layers.first = new_rr->layers.last = NULL;
1258  new_rr->views.first = new_rr->views.last = NULL;
1259  for (RenderLayer *rl = rr->layers.first; rl != NULL; rl = rl->next) {
1260  RenderLayer *new_rl = duplicate_render_layer(rl);
1261  BLI_addtail(&new_rr->layers, new_rl);
1262  }
1263  for (RenderView *rview = rr->views.first; rview != NULL; rview = rview->next) {
1264  RenderView *new_rview = duplicate_render_view(rview);
1265  BLI_addtail(&new_rr->views, new_rview);
1266  }
1267  if (new_rr->rect32 != NULL) {
1268  new_rr->rect32 = MEM_dupallocN(new_rr->rect32);
1269  }
1270  if (new_rr->rectf != NULL) {
1271  new_rr->rectf = MEM_dupallocN(new_rr->rectf);
1272  }
1273  if (new_rr->rectz != NULL) {
1274  new_rr->rectz = MEM_dupallocN(new_rr->rectz);
1275  }
1276  new_rr->stamp_data = BKE_stamp_data_copy(new_rr->stamp_data);
1277  return new_rr;
1278 }
typedef float(TangentPoint)[2]
const char * BKE_tempdir_base(void)
Definition: appdir.c:1154
Camera data-block and utility functions.
void BKE_stamp_data_free(struct StampData *stamp_data)
struct StampData * BKE_stamp_data_copy(const struct StampData *stamp_data)
char BKE_imtype_valid_depths(char imtype)
bool BKE_image_render_write_exr(struct ReportList *reports, const struct RenderResult *rr, const char *filepath, const struct ImageFormatData *imf, const bool save_as_render, const char *view, int layer)
const char * BKE_main_blendfile_path_from_global(void)
Definition: main.c:562
bool BKE_scene_multiview_is_render_view_active(const struct RenderData *rd, const struct SceneRenderView *srv)
#define BLI_assert(a)
Definition: BLI_assert.h:46
void * BLI_hash_md5_buffer(const char *buffer, size_t len, void *resblock)
Definition: hash_md5.c:345
char * BLI_hash_md5_to_hexdigest(void *resblock, char r_hex_digest[33])
Definition: hash_md5.c:381
BLI_INLINE bool BLI_listbase_is_empty(const struct ListBase *lb)
Definition: BLI_listbase.h:269
void BLI_addhead(struct ListBase *listbase, void *vlink) ATTR_NONNULL(1)
Definition: listbase.c:60
#define LISTBASE_FOREACH(type, var, list)
Definition: BLI_listbase.h:336
void BLI_insertlinkafter(struct ListBase *listbase, void *vprevlink, void *vnewlink) ATTR_NONNULL(1)
Definition: listbase.c:301
int BLI_listbase_count_at_most(const struct ListBase *listbase, int count_max) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
void void BLI_listbase_sort(struct ListBase *listbase, int(*cmp)(const void *, const void *)) ATTR_NONNULL(1
void BLI_addtail(struct ListBase *listbase, void *vlink) ATTR_NONNULL(1)
Definition: listbase.c:80
void BLI_remlink(struct ListBase *listbase, void *vlink) ATTR_NONNULL(1)
Definition: listbase.c:100
int BLI_findstringindex(const struct ListBase *listbase, const char *id, int offset) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
void * BLI_findlink(const struct ListBase *listbase, int number) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
void * BLI_findstring(const struct ListBase *listbase, const char *id, int offset) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
#define FILE_MAXFILE
void BLI_split_dirfile(const char *string, char *dir, char *file, size_t dirlen, size_t filelen)
Definition: path_util.c:1465
#define FILE_MAX
void BLI_make_file_string(const char *relabase, char *string, const char *dir, const char *file)
Definition: path_util.c:1206
bool BLI_path_extension_replace(char *path, size_t maxlen, const char *ext) ATTR_NONNULL()
Definition: path_util.c:1393
#define FILE_MAXDIR
BLI_INLINE int BLI_rcti_size_y(const struct rcti *rct)
Definition: BLI_rect.h:190
BLI_INLINE int BLI_rcti_size_x(const struct rcti *rct)
Definition: BLI_rect.h:186
BLI_INLINE int BLI_rcti_cent_y(const struct rcti *rct)
Definition: BLI_rect.h:173
BLI_INLINE int BLI_rcti_cent_x(const struct rcti *rct)
Definition: BLI_rect.h:169
size_t BLI_str_partition(const char *str, const char delim[], const char **sep, const char **suf) ATTR_NONNULL()
Definition: string.c:989
char * BLI_strncpy(char *__restrict dst, const char *__restrict src, size_t maxncpy) ATTR_NONNULL()
Definition: string.c:64
size_t BLI_snprintf(char *__restrict dst, size_t maxncpy, const char *__restrict format,...) ATTR_NONNULL(1
char * BLI_string_join_array_by_sep_char(char *result, size_t result_len, char sep, const char *strings[], uint strings_len) ATTR_NONNULL()
Definition: string_utils.c:364
#define ARRAY_SET_ITEMS(...)
#define STREQ(a, b)
const char * dirname(char *path)
#define PASS_VECTOR_MAX
#define MAX_ID_NAME
Definition: DNA_ID.h:337
#define RE_PASSNAME_COMBINED
#define STEREO_LEFT_NAME
#define RE_PASSNAME_UV
#define R_MULTIVIEW
#define R_IMF_PLANES_BW
#define RE_PASSNAME_DIFFUSE_INDIRECT
#define RE_PASSNAME_INDEXMA
#define RE_PASSNAME_SUBSURFACE_DIRECT
#define RE_PASSNAME_NORMAL
#define RE_PASSNAME_TRANSM_DIRECT
#define RE_PASSNAME_VECTOR
#define RE_PASSNAME_TRANSM_COLOR
#define RE_PASSNAME_EMIT
#define RE_PASSNAME_SUBSURFACE_INDIRECT
#define RE_PASSNAME_GLOSSY_COLOR
#define RE_PASSNAME_SUBSURFACE_COLOR
#define R_BUTS_PREVIEW
#define RE_PASSNAME_TRANSM_INDIRECT
#define RE_PASSNAME_GLOSSY_DIRECT
#define RE_PASSNAME_SHADOW
#define RE_PASSNAME_MIST
#define RE_PASSNAME_ENVIRONMENT
#define RE_PASSNAME_POSITION
@ R_IMF_CHAN_DEPTH_24
@ R_IMF_CHAN_DEPTH_8
@ R_IMF_CHAN_DEPTH_16
@ R_IMF_CHAN_DEPTH_12
@ R_IMF_CHAN_DEPTH_32
#define RE_PASSNAME_DIFFUSE_COLOR
#define SCE_LAY_FLAG_DEFAULT
#define RE_PASSNAME_GLOSSY_INDIRECT
#define RE_PASSNAME_AO
#define RE_PASSNAME_Z
#define STEREO_RIGHT_NAME
#define RE_PASSNAME_DIFFUSE_DIRECT
#define RE_PASSNAME_INDEXOB
@ SCE_PASS_NORMAL
@ SCE_PASS_GLOSSY_DIRECT
@ SCE_PASS_AO
@ SCE_PASS_DIFFUSE_COLOR
@ SCE_PASS_POSITION
@ SCE_PASS_UV
@ SCE_PASS_SUBSURFACE_INDIRECT
@ SCE_PASS_TRANSM_DIRECT
@ SCE_PASS_SUBSURFACE_COLOR
@ SCE_PASS_GLOSSY_COLOR
@ SCE_PASS_DIFFUSE_DIRECT
@ SCE_PASS_GLOSSY_INDIRECT
@ SCE_PASS_INDEXMA
@ SCE_PASS_INDEXOB
@ SCE_PASS_TRANSM_INDIRECT
@ SCE_PASS_COMBINED
@ SCE_PASS_Z
@ SCE_PASS_VECTOR
@ SCE_PASS_DIFFUSE_INDIRECT
@ SCE_PASS_SUBSURFACE_DIRECT
@ SCE_PASS_SHADOW
@ SCE_PASS_TRANSM_COLOR
@ SCE_PASS_MIST
@ SCE_PASS_EMIT
@ SCE_PASS_ENVIRONMENT
static AppView * view
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint y
#define Z
Definition: GeomUtils.cpp:201
void IMB_display_buffer_transform_apply(unsigned char *display_buffer, float *linear_buffer, int width, int height, int channels, const struct ColorManagedViewSettings *view_settings, const struct ColorManagedDisplaySettings *display_settings, bool predivide)
@ COLOR_ROLE_SCENE_LINEAR
const char * IMB_colormanagement_role_colorspace_name_get(int role)
void IMB_colormanagement_transform(float *buffer, int width, int height, int channels, const char *from_colorspace, const char *to_colorspace, bool predivide)
void IMB_float_from_rect(struct ImBuf *ibuf)
Definition: divers.c:805
void IMB_color_to_bw(struct ImBuf *ibuf)
Definition: divers.c:844
struct ImBuf * IMB_allocImBuf(unsigned int x, unsigned int y, unsigned char planes, unsigned int flags)
Definition: allocimbuf.c:500
struct ImBuf * IMB_dupImBuf(const struct ImBuf *ibuf1)
Contains defines and structs used throughout the imbuf module.
void IMB_exr_add_channel(void *handle, const char *layname, const char *passname, const char *view, int xstride, int ystride, float *rect, bool use_half_float)
#define EXR_LAY_MAXNAME
Definition: IMB_openexr.h:14
void IMB_exr_close(void *handle)
#define EXR_VIEW_MAXNAME
Definition: IMB_openexr.h:16
bool IMB_exr_begin_read(void *handle, const char *filepath, int *width, int *height, bool parse_channels)
#define EXR_PASS_MAXNAME
Definition: IMB_openexr.h:15
void IMB_exr_read_channels(void *handle)
void IMB_exr_set_channel(void *handle, const char *layname, const char *passname, int xstride, int ystride, float *rect)
void * IMB_exr_get_handle(void)
void IMB_exr_multilayer_convert(void *handle, void *base, void *(*addview)(void *base, const char *str), void *(*addlayer)(void *base, const char *str), void(*addpass)(void *base, void *lay, const char *str, float *rect, int totchan, const char *chan_id, const char *view))
Read Guarded memory(de)allocation.
#define MEM_SAFE_FREE(v)
Group Output data from inside of a node group A color picker Mix two input colors RGB to Convert a color s luminance to a grayscale value NORMAL
Group Output data from inside of a node group A color picker Mix two input colors RGB to Convert a color s luminance to a grayscale value Generate a normal vector and a dot product Bright Control the brightness and contrast of the input color Vector Map an input vectors to used to fine tune the interpolation of the input Camera Retrieve information about the camera and how it relates to the current shading point s position Clamp a value between a minimum and a maximum Vector Perform vector math operation Invert a producing a negative Combine Generate a color from its and blue channels(Deprecated)") DefNode(ShaderNode
unsigned int U
Definition: btGjkEpa3.h:78
SyclQueue void void * src
int len
Definition: draw_manager.c:108
#define str(s)
void IMB_freeImBuf(ImBuf *UNUSED(ibuf))
ccl_global const KernelWorkTile * tile
void(* MEM_freeN)(void *vmemh)
Definition: mallocn.c:27
void *(* MEM_dupallocN)(const void *vmemh)
Definition: mallocn.c:28
void *(* MEM_callocN)(size_t len, const char *str)
Definition: mallocn.c:31
void *(* MEM_mallocN)(size_t len, const char *str)
Definition: mallocn.c:33
static unsigned a[3]
Definition: RandGen.cpp:78
static const pxr::TfToken b("b", pxr::TfToken::Immortal)
void RE_FreeRenderResult(RenderResult *rr)
Definition: pipeline.c:233
RenderLayer * RE_GetRenderLayer(RenderResult *rr, const char *name)
Definition: pipeline.c:244
static int order_render_passes(const void *a, const void *b)
static void render_result_views_free(RenderResult *rr)
Definition: render_result.c:46
void render_result_single_layer_end(Render *re)
void render_result_exr_file_cache_write(Render *re)
RenderView * RE_RenderViewGetById(RenderResult *rr, const int view_id)
static void * ml_addview_cb(void *base, const char *str)
bool RE_HasFloatPixels(const RenderResult *rr)
bool render_result_exr_file_cache_read(Render *re)
void RE_render_result_rect_from_ibuf(RenderResult *rr, const ImBuf *ibuf, const int view_id)
void render_result_rect_fill_zero(RenderResult *rr, const int view_id)
void render_result_views_shallowdelete(RenderResult *rr)
void render_result_views_new(RenderResult *rr, const RenderData *rd)
static void * ml_addlayer_cb(void *base, const char *str)
RenderPass * render_layer_add_pass(RenderResult *rr, RenderLayer *rl, int channels, const char *name, const char *viewname, const char *chan_id, const bool allocate)
bool RE_RenderResult_is_stereo(const RenderResult *rr)
void render_result_merge(RenderResult *rr, RenderResult *rrpart)
int render_result_exr_file_read_path(RenderResult *rr, RenderLayer *rl_single, const char *filepath)
void render_result_view_new(RenderResult *rr, const char *viewname)
bool RE_HasCombinedLayer(const RenderResult *rr)
RenderResult * render_result_new_from_exr(void *exrhandle, const char *colorspace, bool predivide, int rectx, int recty)
void render_result_passes_allocated_ensure(RenderResult *rr)
static void render_layer_allocate_pass(RenderResult *rr, RenderPass *rp)
void render_result_free(RenderResult *rr)
Definition: render_result.c:70
void render_result_rect_get_pixels(RenderResult *rr, unsigned int *rect, int rectx, int recty, const ColorManagedViewSettings *view_settings, const ColorManagedDisplaySettings *display_settings, const int view_id)
RenderResult * render_result_new(Render *re, rcti *partrct, const char *layername, const char *viewname)
void render_result_clone_passes(Render *re, RenderResult *rr, const char *viewname)
ImBuf * RE_render_result_rect_to_ibuf(RenderResult *rr, const ImageFormatData *imf, const float dither, const int view_id)
RenderView * RE_RenderViewGetByName(RenderResult *rr, const char *viewname)
void render_result_free_list(ListBase *lb, RenderResult *rr)
void RE_render_result_full_channel_name(char *fullname, const char *layname, const char *passname, const char *viewname, const char *chan_id, const int channel)
static int passtype_from_name(const char *name)
void render_result_single_layer_begin(Render *re)
static void ml_addpass_cb(void *base, void *lay, const char *name, float *rect, int totchan, const char *chan_id, const char *view)
static RenderPass * duplicate_render_pass(RenderPass *rpass)
#define CHECK_PASS(NAME)
static RenderLayer * duplicate_render_layer(RenderLayer *rl)
static RenderView * duplicate_render_view(RenderView *rview)
void RE_create_render_pass(RenderResult *rr, const char *name, int channels, const char *chan_id, const char *layername, const char *viewname, const bool allocate)
#define RENDER_LAYER_ADD_PASS_SAFE(rr, rl, channels, name, viewname, chan_id)
RenderResult * RE_DuplicateRenderResult(RenderResult *rr)
static void render_result_exr_file_cache_path(Scene *sce, const char *root, char *r_path)
static void do_merge_tile(RenderResult *rr, RenderResult *rrpart, float *target, float *tile, int pixsize)
void render_result_views_shallowcopy(RenderResult *dst, RenderResult *src)
#define FOREACH_VIEW_LAYER_TO_RENDER_END
#define FOREACH_VIEW_LAYER_TO_RENDER_BEGIN(re_, iter_)
char name[66]
Definition: DNA_ID.h:378
float * zbuf_float
float dither
unsigned int * rect
float * rect_float
void * last
Definition: DNA_listBase.h:31
void * first
Definition: DNA_listBase.h:31
ListBase views
ListBase passes
Definition: RE_pipeline.h:95
char name[RE_MAXNAME]
Definition: RE_pipeline.h:87
struct RenderLayer * next
Definition: RE_pipeline.h:84
void * exrhandle
Definition: RE_pipeline.h:93
struct RenderLayer * prev
Definition: RE_pipeline.h:84
char chan_id[8]
Definition: RE_pipeline.h:66
char name[64]
Definition: RE_pipeline.h:65
char fullname[64]
Definition: RE_pipeline.h:70
char view[64]
Definition: RE_pipeline.h:71
int channels
Definition: RE_pipeline.h:64
float * rect
Definition: RE_pipeline.h:67
struct RenderPass * prev
Definition: RE_pipeline.h:63
struct RenderPass * next
Definition: RE_pipeline.h:63
struct RenderResult * next
Definition: RE_pipeline.h:100
ListBase views
Definition: RE_pipeline.h:125
ListBase layers
Definition: RE_pipeline.h:122
float * rectz
Definition: RE_pipeline.h:114
struct RenderResult * prev
Definition: RE_pipeline.h:100
char * error
Definition: RE_pipeline.h:139
struct StampData * stamp_data
Definition: RE_pipeline.h:141
float * rectf
Definition: RE_pipeline.h:112
bool passes_allocated
Definition: RE_pipeline.h:143
float * rectf
Definition: RE_pipeline.h:54
float * rectz
Definition: RE_pipeline.h:56
int * rect32
Definition: RE_pipeline.h:58
struct RenderView * next
Definition: RE_pipeline.h:50
char name[64]
Definition: RE_pipeline.h:51
RenderResult * result
Definition: render_types.h:49
RenderResult * pushedresult
Definition: render_types.h:51
RenderData r
Definition: render_types.h:82
int winy
Definition: render_types.h:65
int active_view_layer
Definition: render_types.h:84
Scene * scene
Definition: render_types.h:81
int winx
Definition: render_types.h:65
rcti disprect
Definition: render_types.h:66
ListBase view_layers
Definition: render_types.h:83
struct SceneRenderView * next
struct ViewLayer * next
char name[64]
int ymin
Definition: DNA_vec_types.h:64
int ymax
Definition: DNA_vec_types.h:64
int xmin
Definition: DNA_vec_types.h:63
int xmax
Definition: DNA_vec_types.h:63