Blender  V3.3
pipeline.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 <limits.h>
10 #include <math.h>
11 #include <stddef.h>
12 #include <stdlib.h>
13 #include <string.h>
14 
15 #include "DNA_anim_types.h"
16 #include "DNA_collection_types.h"
17 #include "DNA_image_types.h"
18 #include "DNA_node_types.h"
19 #include "DNA_object_types.h"
20 #include "DNA_particle_types.h"
21 #include "DNA_scene_types.h"
22 #include "DNA_sequence_types.h"
23 #include "DNA_space_types.h"
24 #include "DNA_userdef_types.h"
25 
26 #include "MEM_guardedalloc.h"
27 
28 #include "BLI_fileops.h"
29 #include "BLI_listbase.h"
30 #include "BLI_math.h"
31 #include "BLI_path_util.h"
32 #include "BLI_rect.h"
33 #include "BLI_string.h"
34 #include "BLI_threads.h"
35 #include "BLI_timecode.h"
36 
37 #include "BLT_translation.h"
38 
39 #include "BKE_anim_data.h"
40 #include "BKE_animsys.h" /* <------ should this be here?, needed for sequencer update */
41 #include "BKE_callbacks.h"
42 #include "BKE_camera.h"
43 #include "BKE_colortools.h"
44 #include "BKE_context.h" /* XXX needed by wm_window.h */
45 #include "BKE_global.h"
46 #include "BKE_image.h"
47 #include "BKE_image_format.h"
48 #include "BKE_image_save.h"
49 #include "BKE_layer.h"
50 #include "BKE_lib_id.h"
51 #include "BKE_lib_remap.h"
52 #include "BKE_mask.h"
53 #include "BKE_modifier.h"
54 #include "BKE_node.h"
55 #include "BKE_object.h"
56 #include "BKE_pointcache.h"
57 #include "BKE_report.h"
58 #include "BKE_scene.h"
59 #include "BKE_sound.h"
60 #include "BKE_writeavi.h" /* <------ should be replaced once with generic movie module */
61 
62 #include "NOD_composite.h"
63 
64 #include "DEG_depsgraph.h"
65 #include "DEG_depsgraph_build.h"
66 #include "DEG_depsgraph_debug.h"
67 #include "DEG_depsgraph_query.h"
68 
69 #include "IMB_colormanagement.h"
70 #include "IMB_imbuf.h"
71 #include "IMB_imbuf_types.h"
72 #include "IMB_metadata.h"
73 #include "PIL_time.h"
74 
75 #include "RE_engine.h"
76 #include "RE_pipeline.h"
77 #include "RE_texture.h"
78 
79 #include "SEQ_relations.h"
80 #include "SEQ_render.h"
81 
82 #include "../../windowmanager/WM_api.h" /* XXX */
83 #include "../../windowmanager/wm_window.h" /* XXX */
84 #include "GPU_context.h"
85 
86 #ifdef WITH_FREESTYLE
87 # include "FRS_freestyle.h"
88 #endif
89 
90 /* internal */
91 #include "pipeline.h"
92 #include "render_result.h"
93 #include "render_types.h"
94 
95 /* render flow
96  *
97  * 1) Initialize state
98  * - state data, tables
99  * - movie/image file init
100  * - everything that doesn't change during animation
101  *
102  * 2) Initialize data
103  * - camera, world, matrices
104  * - make render verts, faces, halos, strands
105  * - everything can change per frame/field
106  *
107  * 3) Render Processor
108  * - multiple layers
109  * - tiles, rect, baking
110  * - layers/tiles optionally to disk or directly in Render Result
111  *
112  * 4) Composite Render Result
113  * - also read external files etc
114  *
115  * 5) Image Files
116  * - save file or append in movie
117  */
118 
119 /* -------------------------------------------------------------------- */
123 /* here we store all renders */
124 static struct {
127 
130 /* -------------------------------------------------------------------- */
134 static void render_callback_exec_null(Render *re, Main *bmain, eCbEvent evt)
135 {
136  if (re->r.scemode & R_BUTS_PREVIEW) {
137  return;
138  }
139  BKE_callback_exec_null(bmain, evt);
140 }
141 
142 static void render_callback_exec_id(Render *re, Main *bmain, ID *id, eCbEvent evt)
143 {
144  if (re->r.scemode & R_BUTS_PREVIEW) {
145  return;
146  }
147  BKE_callback_exec_id(bmain, id, evt);
148 }
149 
152 /* -------------------------------------------------------------------- */
156 static bool do_write_image_or_movie(Render *re,
157  Main *bmain,
158  Scene *scene,
159  bMovieHandle *mh,
160  const int totvideos,
161  const char *name_override);
162 
163 /* default callbacks, set in each new render */
164 static void result_nothing(void *UNUSED(arg), RenderResult *UNUSED(rr))
165 {
166 }
167 static void result_rcti_nothing(void *UNUSED(arg),
168  RenderResult *UNUSED(rr),
169  struct rcti *UNUSED(rect))
170 {
171 }
172 static void current_scene_nothing(void *UNUSED(arg), Scene *UNUSED(scene))
173 {
174 }
175 static void stats_nothing(void *UNUSED(arg), RenderStats *UNUSED(rs))
176 {
177 }
178 static void float_nothing(void *UNUSED(arg), float UNUSED(val))
179 {
180 }
181 static int default_break(void *UNUSED(arg))
182 {
183  return G.is_break == true;
184 }
185 
186 static void stats_background(void *UNUSED(arg), RenderStats *rs)
187 {
188  if (rs->infostr == NULL) {
189  return;
190  }
191 
192  uintptr_t mem_in_use, peak_memory;
193  float megs_used_memory, megs_peak_memory;
194  char info_time_str[32];
195 
197  peak_memory = MEM_get_peak_memory();
198 
199  megs_used_memory = (mem_in_use) / (1024.0 * 1024.0);
200  megs_peak_memory = (peak_memory) / (1024.0 * 1024.0);
201 
203  info_time_str, sizeof(info_time_str), PIL_check_seconds_timer() - rs->starttime);
204 
205  /* Compositor calls this from multiple threads, mutex lock to ensure we don't
206  * get garbled output. */
209 
210  fprintf(stdout,
211  TIP_("Fra:%d Mem:%.2fM (Peak %.2fM) "),
212  rs->cfra,
213  megs_used_memory,
214  megs_peak_memory);
215 
216  fprintf(stdout, TIP_("| Time:%s | "), info_time_str);
217 
218  fprintf(stdout, "%s", rs->infostr);
219 
220  /* Flush stdout to be sure python callbacks are printing stuff after blender. */
221  fflush(stdout);
222 
223  /* NOTE: using G_MAIN seems valid here???
224  * Not sure it's actually even used anyway, we could as well pass NULL? */
226 
227  fputc('\n', stdout);
228  fflush(stdout);
229 
231 }
232 
234 {
235  render_result_free(rr);
236 }
237 
238 float *RE_RenderLayerGetPass(RenderLayer *rl, const char *name, const char *viewname)
239 {
240  RenderPass *rpass = RE_pass_find_by_name(rl, name, viewname);
241  return rpass ? rpass->rect : NULL;
242 }
243 
245 {
246  if (rr == NULL) {
247  return NULL;
248  }
249 
250  return BLI_findstring(&rr->layers, name, offsetof(RenderLayer, name));
251 }
252 
254 {
255  return (re->r.scemode & R_SINGLE_LAYER);
256 }
257 
259  void *exrhandle, const char *colorspace, bool predivide, int rectx, int recty)
260 {
261  return render_result_new_from_exr(exrhandle, colorspace, predivide, rectx, recty);
262 }
263 
265 {
266  ViewLayer *view_layer = BLI_findlink(&re->view_layers, re->active_view_layer);
267 
268  if (view_layer) {
269  RenderLayer *rl = BLI_findstring(&rr->layers, view_layer->name, offsetof(RenderLayer, name));
270 
271  if (rl) {
272  return rl;
273  }
274  }
275 
276  return rr->layers.first;
277 }
278 
280 {
281  if (single_layer) {
282  return true;
283  }
284 
285  ViewLayer *view_layer;
286  for (view_layer = scene->view_layers.first; view_layer; view_layer = view_layer->next) {
287  if (view_layer->flag & VIEW_LAYER_RENDER) {
288  return true;
289  }
290  }
291  return false;
292 }
293 
296 /* -------------------------------------------------------------------- */
300 Render *RE_GetRender(const char *name)
301 {
302  Render *re;
303 
304  /* search for existing renders */
305  for (re = RenderGlobal.renderlist.first; re; re = re->next) {
306  if (STREQLEN(re->name, name, RE_MAXNAME)) {
307  break;
308  }
309  }
310 
311  return re;
312 }
313 
315 {
316  if (re) {
318  return re->result;
319  }
320 
321  return NULL;
322 }
323 
325 {
326  if (re) {
329  return re->result;
330  }
331 
332  return NULL;
333 }
334 
336 {
337  if (re) {
339  re->result = NULL;
340  }
341 }
342 
344 {
345  /* for keeping render buffers */
346  if (re) {
347  SWAP(RenderResult *, re->result, *rr);
348  }
349 }
350 
352 {
353  if (re) {
355  }
356 }
357 
359 {
360  if (re) {
361  return re->scene;
362  }
363  return NULL;
364 }
365 
366 void RE_SetScene(Render *re, Scene *sce)
367 {
368  if (re) {
369  re->scene = sce;
370  }
371 }
372 
374 {
375  memset(rr, 0, sizeof(RenderResult));
376 
377  if (re) {
379 
380  if (re->result) {
381  RenderLayer *rl;
382  RenderView *rv, *rview;
383 
384  rr->rectx = re->result->rectx;
385  rr->recty = re->result->recty;
386 
387  /* creates a temporary duplication of views */
389 
390  rv = rr->views.first;
391  rr->have_combined = (rv->rectf != NULL);
392 
393  /* active layer */
394  rl = render_get_active_layer(re, re->result);
395 
396  if (rl) {
397  if (rv->rectf == NULL) {
398  for (rview = (RenderView *)rr->views.first; rview; rview = rview->next) {
400  }
401  }
402 
403  if (rv->rectz == NULL) {
404  for (rview = (RenderView *)rr->views.first; rview; rview = rview->next) {
405  rview->rectz = RE_RenderLayerGetPass(rl, RE_PASSNAME_Z, rview->name);
406  }
407  }
408  }
409 
410  rr->layers = re->result->layers;
411  rr->xof = re->disprect.xmin;
412  rr->yof = re->disprect.ymin;
413  rr->stamp_data = re->result->stamp_data;
414  }
415  }
416 }
417 
419 {
420  if (re) {
421  if (rr) {
423  }
425  }
426 }
427 
428 void RE_AcquireResultImage(Render *re, RenderResult *rr, const int view_id)
429 {
430  memset(rr, 0, sizeof(RenderResult));
431 
432  if (re) {
434 
435  if (re->result) {
436  RenderLayer *rl;
437  RenderView *rv;
438 
439  rr->rectx = re->result->rectx;
440  rr->recty = re->result->recty;
441 
442  /* actview view */
443  rv = RE_RenderViewGetById(re->result, view_id);
444  rr->have_combined = (rv->rectf != NULL);
445 
446  rr->rectf = rv->rectf;
447  rr->rectz = rv->rectz;
448  rr->rect32 = rv->rect32;
449 
450  /* active layer */
451  rl = render_get_active_layer(re, re->result);
452 
453  if (rl) {
454  if (rv->rectf == NULL) {
456  }
457 
458  if (rv->rectz == NULL) {
460  }
461  }
462 
463  rr->layers = re->result->layers;
464  rr->views = re->result->views;
465 
466  rr->xof = re->disprect.xmin;
467  rr->yof = re->disprect.ymin;
468 
469  rr->stamp_data = re->result->stamp_data;
470  }
471  }
472 }
473 
475 {
476  if (re) {
478  }
479 }
480 
481 void RE_ResultGet32(Render *re, unsigned int *rect)
482 {
483  RenderResult rres;
484  const int view_id = BKE_scene_multiview_view_id_get(&re->r, re->viewname);
485 
486  RE_AcquireResultImageViews(re, &rres);
488  rect,
489  re->rectx,
490  re->recty,
491  &re->scene->view_settings,
492  &re->scene->display_settings,
493  view_id);
494  RE_ReleaseResultImageViews(re, &rres);
495 }
496 
499  unsigned int *rect,
500  const int view_id)
501 {
503  rect,
504  re->rectx,
505  re->recty,
506  &re->scene->view_settings,
507  &re->scene->display_settings,
508  view_id);
509 }
510 
512 {
513  return &re->i;
514 }
515 
516 Render *RE_NewRender(const char *name)
517 {
518  Render *re;
519 
520  /* only one render per name exists */
521  re = RE_GetRender(name);
522  if (re == NULL) {
523 
524  /* new render data struct */
525  re = MEM_callocN(sizeof(Render), "new render");
526  BLI_addtail(&RenderGlobal.renderlist, re);
527  BLI_strncpy(re->name, name, RE_MAXNAME);
531  }
532 
533  RE_InitRenderCB(re);
534 
535  return re;
536 }
537 
538 /* MAX_ID_NAME + sizeof(Library->name) + space + null-terminator. */
539 #define MAX_SCENE_RENDER_NAME (MAX_ID_NAME + 1024 + 2)
540 
541 static void scene_render_name_get(const Scene *scene, const size_t max_size, char *render_name)
542 {
543  if (ID_IS_LINKED(scene)) {
544  BLI_snprintf(render_name, max_size, "%s %s", scene->id.lib->id.name, scene->id.name);
545  }
546  else {
547  BLI_snprintf(render_name, max_size, "%s", scene->id.name);
548  }
549 }
550 
552 {
553  char render_name[MAX_SCENE_RENDER_NAME];
554  scene_render_name_get(scene, sizeof(render_name), render_name);
555  return RE_GetRender(render_name);
556 }
557 
559 {
560  char render_name[MAX_SCENE_RENDER_NAME];
561  scene_render_name_get(scene, sizeof(render_name), render_name);
562  return RE_NewRender(render_name);
563 }
564 
566 {
567  /* set default empty callbacks */
572  re->progress = float_nothing;
574  if (G.background) {
576  }
577  else {
579  }
580  /* clear callback handles */
581  re->dih = re->dch = re->duh = re->sdh = re->prh = re->tbh = NULL;
582 }
583 
585 {
586  if (re->engine) {
587  RE_engine_free(re->engine);
588  }
589 
593 
595  BLI_freelistN(&re->r.views);
596 
598 
599  if (re->highlighted_tiles != NULL) {
601  }
602 
603  /* main dbase can already be invalid now, some database-free code checks it */
604  re->main = NULL;
605  re->scene = NULL;
606 
609 
610  BLI_remlink(&RenderGlobal.renderlist, re);
611  MEM_freeN(re);
612 }
613 
615 {
616  while (RenderGlobal.renderlist.first) {
617  RE_FreeRender(RenderGlobal.renderlist.first);
618  }
619 
620 #ifdef WITH_FREESTYLE
621  /* finalize Freestyle */
622  FRS_exit();
623 #endif
624 }
625 
627 {
628  Render *re;
629 
630  for (re = RenderGlobal.renderlist.first; re; re = re->next) {
633 
634  re->result = NULL;
635  re->pushedresult = NULL;
636  }
637 }
638 
640 {
641  Render *re;
642  for (re = RenderGlobal.renderlist.first; re != NULL; re = re->next) {
643  if (re->engine != NULL) {
645  RE_engine_free(re->engine);
646  re->engine = NULL;
647  }
648  }
649 }
650 
652 {
653  /* If engine is currently rendering, just wait for it to be freed when it finishes rendering. */
654  if (re->engine && !(re->engine->flag & RE_ENGINE_RENDERING)) {
655  RE_engine_free(re->engine);
656  re->engine = NULL;
657  }
658 }
659 
661 {
662  /* Render engines can be kept around for quick re-render, this clears all or one scene. */
663  if (scene) {
665  if (re) {
667  }
668  }
669  else {
670  for (Render *re = RenderGlobal.renderlist.first; re; re = re->next) {
672  }
673  }
674 }
675 
678 /* -------------------------------------------------------------------- */
682 static void re_init_resolution(Render *re, Render *source, int winx, int winy, rcti *disprect)
683 {
684  re->winx = winx;
685  re->winy = winy;
686  if (source && (source->r.mode & R_BORDER)) {
687  /* NOTE(@sergey): doesn't seem original bordered `disprect` is storing anywhere
688  * after insertion on black happening in #do_render_engine(),
689  * so for now simply re-calculate `disprect` using border from source renderer. */
690 
691  re->disprect.xmin = source->r.border.xmin * winx;
692  re->disprect.xmax = source->r.border.xmax * winx;
693 
694  re->disprect.ymin = source->r.border.ymin * winy;
695  re->disprect.ymax = source->r.border.ymax * winy;
696 
697  re->rectx = BLI_rcti_size_x(&re->disprect);
698  re->recty = BLI_rcti_size_y(&re->disprect);
699 
700  /* copy border itself, since it could be used by external engines */
701  re->r.border = source->r.border;
702  }
703  else if (disprect) {
704  re->disprect = *disprect;
705  re->rectx = BLI_rcti_size_x(&re->disprect);
706  re->recty = BLI_rcti_size_y(&re->disprect);
707  }
708  else {
709  re->disprect.xmin = re->disprect.ymin = 0;
710  re->disprect.xmax = winx;
711  re->disprect.ymax = winy;
712  re->rectx = winx;
713  re->recty = winy;
714  }
715 }
716 
718 {
719  BLI_freelistN(&to->views);
721 
722  *to = *from;
723 
724  BLI_duplicatelist(&to->views, &from->views);
725  BKE_curvemapping_copy_data(&to->mblur_shutter_curve, &from->mblur_shutter_curve);
726 }
727 
729  Render *source,
730  RenderData *rd,
731  ListBase *render_layers,
732  ViewLayer *single_layer,
733  int winx,
734  int winy,
735  rcti *disprect)
736 {
737  bool had_freestyle = (re->r.mode & R_EDGE_FRS) != 0;
738 
739  re->ok = true; /* maybe flag */
740 
742 
743  /* copy render data and render layers for thread safety */
744  render_copy_renderdata(&re->r, rd);
746  BLI_duplicatelist(&re->view_layers, render_layers);
747  re->active_view_layer = 0;
748 
749  if (source) {
750  /* reuse border flags from source renderer */
751  re->r.mode &= ~(R_BORDER | R_CROP);
752  re->r.mode |= source->r.mode & (R_BORDER | R_CROP);
753 
754  /* dimensions shall be shared between all renderers */
755  re->r.xsch = source->r.xsch;
756  re->r.ysch = source->r.ysch;
757  re->r.size = source->r.size;
758  }
759 
760  re_init_resolution(re, source, winx, winy, disprect);
761 
762  /* disable border if it's a full render anyway */
763  if (re->r.border.xmin == 0.0f && re->r.border.xmax == 1.0f && re->r.border.ymin == 0.0f &&
764  re->r.border.ymax == 1.0f) {
765  re->r.mode &= ~R_BORDER;
766  }
767 
768  if (re->rectx < 1 || re->recty < 1 ||
769  (BKE_imtype_is_movie(rd->im_format.imtype) && (re->rectx < 16 || re->recty < 16))) {
770  BKE_report(re->reports, RPT_ERROR, "Image too small");
771  re->ok = 0;
772  return;
773  }
774 
775  if (single_layer) {
776  int index = BLI_findindex(render_layers, single_layer);
777  if (index != -1) {
778  re->active_view_layer = index;
779  re->r.scemode |= R_SINGLE_LAYER;
780  }
781  }
782 
783  /* if preview render, we try to keep old result */
785 
786  if (re->r.scemode & R_BUTS_PREVIEW) {
787  if (had_freestyle || (re->r.mode & R_EDGE_FRS)) {
788  /* freestyle manipulates render layers so always have to free */
790  re->result = NULL;
791  }
792  else if (re->result) {
793  ViewLayer *active_render_layer = BLI_findlink(&re->view_layers, re->active_view_layer);
794  RenderLayer *rl;
795  bool have_layer = false;
796 
797  for (rl = re->result->layers.first; rl; rl = rl->next) {
798  if (STREQ(rl->name, active_render_layer->name)) {
799  have_layer = true;
800  }
801  }
802 
803  if (re->result->rectx == re->rectx && re->result->recty == re->recty && have_layer) {
804  /* keep render result, this avoids flickering black tiles
805  * when the preview changes */
806  }
807  else {
808  /* free because resolution changed */
810  re->result = NULL;
811  }
812  }
813  }
814  else {
815 
816  /* make empty render result, so display callbacks can initialize */
818  re->result = MEM_callocN(sizeof(RenderResult), "new render result");
819  re->result->rectx = re->rectx;
820  re->result->recty = re->recty;
822  }
823 
825 
827 
829 }
830 
832 {
833  /* filter */
834  re->r.gauss = rd->gauss;
835 
836  /* motion blur */
837  re->r.blurfac = rd->blurfac;
838 
839  /* freestyle */
842 
843  /* render layers */
845  BLI_duplicatelist(&re->view_layers, render_layers);
846 
847  /* render views */
848  BLI_freelistN(&re->r.views);
849  BLI_duplicatelist(&re->r.views, &rd->views);
850 }
851 
852 void RE_display_init_cb(Render *re, void *handle, void (*f)(void *handle, RenderResult *rr))
853 {
854  re->display_init = f;
855  re->dih = handle;
856 }
857 void RE_display_clear_cb(Render *re, void *handle, void (*f)(void *handle, RenderResult *rr))
858 {
859  re->display_clear = f;
860  re->dch = handle;
861 }
863  void *handle,
864  void (*f)(void *handle, RenderResult *rr, rcti *rect))
865 {
866  re->display_update = f;
867  re->duh = handle;
868 }
869 void RE_current_scene_update_cb(Render *re, void *handle, void (*f)(void *handle, Scene *scene))
870 {
871  re->current_scene_update = f;
872  re->suh = handle;
873 }
874 void RE_stats_draw_cb(Render *re, void *handle, void (*f)(void *handle, RenderStats *rs))
875 {
876  re->stats_draw = f;
877  re->sdh = handle;
878 }
879 void RE_progress_cb(Render *re, void *handle, void (*f)(void *handle, float))
880 {
881  re->progress = f;
882  re->prh = handle;
883 }
884 
885 void RE_draw_lock_cb(Render *re, void *handle, void (*f)(void *handle, bool lock))
886 {
887  re->draw_lock = f;
888  re->dlh = handle;
889 }
890 
891 void RE_test_break_cb(Render *re, void *handle, int (*f)(void *handle))
892 {
893  re->test_break = f;
894  re->tbh = handle;
895 }
896 
899 /* -------------------------------------------------------------------- */
904 {
905  /* Needs to be created in the main ogl thread. */
907  /* So we activate the window's one afterwards. */
909 }
910 
912 {
913  /* Needs to be called from the thread which used the ogl context for rendering. */
914  if (re->gl_context) {
915  if (re->gpu_context) {
919  re->gpu_context = NULL;
920  }
921 
923  re->gl_context = NULL;
924  }
925 }
926 
928 {
929  return re->gl_context;
930 }
931 
933 {
934  if (re->gpu_context == NULL) {
936  }
937  return re->gpu_context;
938 }
939 
942 /* -------------------------------------------------------------------- */
950 /* ************ This part uses API, for rendering Blender scenes ********** */
951 
952 /* make sure disprect is not affected by the render border */
954 {
955  re->disprect.xmin = re->disprect.ymin = 0;
956  re->disprect.xmax = re->winx;
957  re->disprect.ymax = re->winy;
958  re->rectx = re->winx;
959  re->recty = re->winy;
960 }
961 
962 static void render_result_uncrop(Render *re)
963 {
964  /* when using border render with crop disabled, insert render result into
965  * full size with black pixels outside */
966  if (re->result && (re->r.mode & R_BORDER)) {
967  if ((re->r.mode & R_CROP) == 0) {
968  RenderResult *rres;
969 
970  /* backup */
971  const rcti orig_disprect = re->disprect;
972  const int orig_rectx = re->rectx, orig_recty = re->recty;
973 
975 
976  /* sub-rect for merge call later on */
977  re->result->tilerect = re->disprect;
978 
979  /* weak is: it chances disprect from border */
981 
984 
985  render_result_clone_passes(re, rres, NULL);
987 
988  render_result_merge(rres, re->result);
990  re->result = rres;
991 
992  /* Weak, the display callback wants an active render-layer pointer. */
994 
996 
997  re->display_init(re->dih, re->result);
998  re->display_update(re->duh, re->result, NULL);
999 
1000  /* restore the disprect from border */
1001  re->disprect = orig_disprect;
1002  re->rectx = orig_rectx;
1003  re->recty = orig_recty;
1004  }
1005  else {
1006  /* set offset (again) for use in compositor, disprect was manipulated. */
1007  re->result->xof = 0;
1008  re->result->yof = 0;
1009  }
1010  }
1011 }
1012 
1013 /* Render scene into render result, with a render engine. */
1014 static void do_render_engine(Render *re)
1015 {
1016  Object *camera = RE_GetCamera(re);
1017  /* also check for camera here */
1018  if (camera == NULL) {
1019  BKE_report(re->reports, RPT_ERROR, "Cannot render, no camera");
1020  G.is_break = true;
1021  return;
1022  }
1023 
1024  /* now use renderdata and camera to set viewplane */
1025  RE_SetCamera(re, camera);
1026 
1027  re->current_scene_update(re->suh, re->scene);
1028  RE_engine_render(re, false);
1029 
1030  /* when border render, check if we have to insert it in black */
1032 }
1033 
1034 /* Render scene into render result, within a compositor node tree.
1035  * Uses the same image dimensions, does not recursively perform compositing. */
1036 static void do_render_compositor_scene(Render *re, Scene *sce, int cfra)
1037 {
1038  Render *resc = RE_NewSceneRender(sce);
1039  int winx = re->winx, winy = re->winy;
1040 
1041  sce->r.cfra = cfra;
1042 
1044 
1045  /* exception: scene uses own size (unfinished code) */
1046  if (0) {
1047  BKE_render_resolution(&sce->r, false, &winx, &winy);
1048  }
1049 
1050  /* initial setup */
1051  RE_InitState(resc, re, &sce->r, &sce->view_layers, NULL, winx, winy, &re->disprect);
1052 
1053  /* We still want to use 'rendercache' setting from org (main) scene... */
1054  resc->r.scemode = (resc->r.scemode & ~R_EXR_CACHE_FILE) | (re->r.scemode & R_EXR_CACHE_FILE);
1055 
1056  /* still unsure entity this... */
1057  resc->main = re->main;
1058  resc->scene = sce;
1059 
1060  /* copy callbacks */
1061  resc->display_update = re->display_update;
1062  resc->duh = re->duh;
1063  resc->test_break = re->test_break;
1064  resc->tbh = re->tbh;
1065  resc->stats_draw = re->stats_draw;
1066  resc->sdh = re->sdh;
1068  resc->suh = re->suh;
1069 
1070  do_render_engine(resc);
1071 }
1072 
1073 /* helper call to detect if this scene needs a render,
1074  * or if there's a any render layer to render. */
1075 static int compositor_needs_render(Scene *sce, int this_scene)
1076 {
1077  bNodeTree *ntree = sce->nodetree;
1078  bNode *node;
1079 
1080  if (ntree == NULL) {
1081  return 1;
1082  }
1083  if (sce->use_nodes == false) {
1084  return 1;
1085  }
1086  if ((sce->r.scemode & R_DOCOMP) == 0) {
1087  return 1;
1088  }
1089 
1090  for (node = ntree->nodes.first; node; node = node->next) {
1091  if (node->type == CMP_NODE_R_LAYERS && (node->flag & NODE_MUTED) == 0) {
1092  if (this_scene == 0 || node->id == NULL || node->id == &sce->id) {
1093  return 1;
1094  }
1095  }
1096  }
1097  return 0;
1098 }
1099 
1100 /* Render all scenes within a compositor node tree. */
1102 {
1103  bNode *node;
1104  int cfra = re->scene->r.cfra;
1105  Scene *restore_scene = re->scene;
1106 
1107  if (re->scene->nodetree == NULL) {
1108  return;
1109  }
1110 
1111  bool changed_scene = false;
1112 
1113  /* now foreach render-result node we do a full render */
1114  /* results are stored in a way compositor will find it */
1115  GSet *scenes_rendered = BLI_gset_ptr_new(__func__);
1116  for (node = re->scene->nodetree->nodes.first; node; node = node->next) {
1117  if (node->type == CMP_NODE_R_LAYERS && (node->flag & NODE_MUTED) == 0) {
1118  if (node->id && node->id != (ID *)re->scene) {
1119  Scene *scene = (Scene *)node->id;
1120  if (!BLI_gset_haskey(scenes_rendered, scene) &&
1122  do_render_compositor_scene(re, scene, cfra);
1123  BLI_gset_add(scenes_rendered, scene);
1124  node->typeinfo->updatefunc(restore_scene->nodetree, node);
1125 
1126  if (scene != re->scene) {
1127  changed_scene = true;
1128  }
1129  }
1130  }
1131  }
1132  }
1133  BLI_gset_free(scenes_rendered, NULL);
1134 
1135  if (changed_scene) {
1136  /* If rendered another scene, switch back to the current scene with compositing nodes. */
1137  re->current_scene_update(re->suh, re->scene);
1138  }
1139 }
1140 
1141 /* bad call... need to think over proper method still */
1142 static void render_compositor_stats(void *arg, const char *str)
1143 {
1144  Render *re = (Render *)arg;
1145 
1146  RenderStats i;
1147  memcpy(&i, &re->i, sizeof(i));
1148  i.infostr = str;
1149  re->stats_draw(re->sdh, &i);
1150 }
1151 
1152 /* Render compositor nodes, along with any scenes required for them.
1153  * The result will be output into a compositing render layer in the render result. */
1155 {
1157  int update_newframe = 0;
1158 
1160  /* save memory... free all cached images */
1162 
1163  /* render the frames
1164  * it could be optimized to render only the needed view
1165  * but what if a scene has a different number of views
1166  * than the main scene? */
1167  do_render_engine(re);
1168  }
1169  else {
1170  re->i.cfra = re->r.cfra;
1171 
1172  /* ensure new result gets added, like for regular renders */
1174 
1176  if ((re->r.mode & R_CROP) == 0) {
1178  }
1180 
1182 
1183  /* scene render process already updates animsys */
1184  update_newframe = 1;
1185  }
1186 
1187  /* swap render result */
1188  if (re->r.scemode & R_SINGLE_LAYER) {
1192  }
1193 
1194  if (!re->test_break(re->tbh)) {
1195 
1196  if (ntree) {
1198  }
1199 
1200  if (ntree && re->scene->use_nodes && re->r.scemode & R_DOCOMP) {
1201  /* checks if there are render-result nodes that need scene */
1202  if ((re->r.scemode & R_SINGLE_LAYER) == 0) {
1204  }
1205 
1206  if (!re->test_break(re->tbh)) {
1208  ntree->test_break = re->test_break;
1209  ntree->progress = re->progress;
1210  ntree->sdh = re;
1211  ntree->tbh = re->tbh;
1212  ntree->prh = re->prh;
1213 
1214  if (update_newframe) {
1215  /* If we have consistent depsgraph now would be a time to update them. */
1216  }
1217 
1218  RenderView *rv;
1219  for (rv = re->result->views.first; rv; rv = rv->next) {
1221  re->pipeline_scene_eval, ntree, &re->r, true, G.background == 0, rv->name);
1222  }
1223 
1224  ntree->stats_draw = NULL;
1225  ntree->test_break = NULL;
1226  ntree->progress = NULL;
1227  ntree->tbh = ntree->sdh = ntree->prh = NULL;
1228  }
1229  }
1230  }
1231 
1232  /* Weak: the display callback wants an active render-layer pointer. */
1233  if (re->result != NULL) {
1234  re->result->renlay = render_get_active_layer(re, re->result);
1235  re->display_update(re->duh, re->result, NULL);
1236  }
1237 }
1238 
1240 {
1241  RenderResult rres;
1242  RenderView *rv;
1243  int nr;
1244 
1245  /* this is the basic trick to get the displayed float or char rect from render result */
1246  nr = 0;
1247  for (rv = re->result->views.first; rv; rv = rv->next, nr++) {
1248  RE_SetActiveRenderView(re, rv->name);
1249  RE_AcquireResultImage(re, &rres, nr);
1250 
1251  Object *ob_camera_eval = DEG_get_evaluated_object(re->pipeline_depsgraph, RE_GetCamera(re));
1253  ob_camera_eval,
1254  (re->r.stamp & R_STAMP_STRIPMETA) ? rres.stamp_data : NULL,
1255  (unsigned char *)rres.rect32,
1256  rres.rectf,
1257  rres.rectx,
1258  rres.recty,
1259  4);
1261  }
1262 }
1263 
1265 {
1266  Editing *ed;
1267  Sequence *seq;
1268 
1269  ed = scene->ed;
1270 
1271  if (!(rd->scemode & R_DOSEQ) || !ed || !ed->seqbase.first) {
1272  return 0;
1273  }
1274 
1275  for (seq = ed->seqbase.first; seq; seq = seq->next) {
1276  if (seq->type != SEQ_TYPE_SOUND_RAM) {
1277  return 1;
1278  }
1279  }
1280 
1281  return 0;
1282 }
1283 
1284 /* Render sequencer strips into render result. */
1285 static void do_render_sequencer(Render *re)
1286 {
1287  static int recurs_depth = 0;
1288  struct ImBuf *out;
1289  RenderResult *rr; /* don't assign re->result here as it might change during give_ibuf_seq */
1290  int cfra = re->r.cfra;
1292  int view_id, tot_views;
1293  struct ImBuf **ibuf_arr;
1294  int re_x, re_y;
1295 
1296  re->i.cfra = cfra;
1297 
1298  recurs_depth++;
1299 
1300  if ((re->r.mode & R_BORDER) && (re->r.mode & R_CROP) == 0) {
1301  /* if border rendering is used and cropping is disabled, final buffer should
1302  * be as large as the whole frame */
1303  re_x = re->winx;
1304  re_y = re->winy;
1305  }
1306  else {
1307  re_x = re->result->rectx;
1308  re_y = re->result->recty;
1309  }
1310 
1311  tot_views = BKE_scene_multiview_num_views_get(&re->r);
1312  ibuf_arr = MEM_mallocN(sizeof(ImBuf *) * tot_views, "Sequencer Views ImBufs");
1313 
1315  re->pipeline_depsgraph,
1316  re->scene,
1317  re_x,
1318  re_y,
1320  true,
1321  &context);
1322 
1323  /* The render-result gets destroyed during the rendering, so we first collect all ibufs
1324  * and then we populate the final render-result. */
1325 
1326  for (view_id = 0; view_id < tot_views; view_id++) {
1327  context.view_id = view_id;
1328  out = SEQ_render_give_ibuf(&context, cfra, 0);
1329 
1330  if (out) {
1331  ibuf_arr[view_id] = IMB_dupImBuf(out);
1332  IMB_metadata_copy(ibuf_arr[view_id], out);
1333  IMB_freeImBuf(out);
1335  }
1336  else {
1337  ibuf_arr[view_id] = NULL;
1338  }
1339  }
1340 
1341  rr = re->result;
1342 
1344  render_result_views_new(rr, &re->r);
1346 
1347  for (view_id = 0; view_id < tot_views; view_id++) {
1348  RenderView *rv = RE_RenderViewGetById(rr, view_id);
1350 
1351  if (ibuf_arr[view_id]) {
1352  /* copy ibuf into combined pixel rect */
1353  RE_render_result_rect_from_ibuf(rr, ibuf_arr[view_id], view_id);
1354 
1355  if (ibuf_arr[view_id]->metadata && (re->r.stamp & R_STAMP_STRIPMETA)) {
1356  /* ensure render stamp info first */
1358  BKE_stamp_info_from_imbuf(rr, ibuf_arr[view_id]);
1359  }
1360 
1361  if (recurs_depth == 0) { /* With nested scenes, only free on top-level. */
1362  Editing *ed = re->pipeline_scene_eval->ed;
1363  if (ed) {
1365  }
1366  }
1367  IMB_freeImBuf(ibuf_arr[view_id]);
1368  }
1369  else {
1370  /* render result is delivered empty in most cases, nevertheless we handle all cases */
1371  render_result_rect_fill_zero(rr, view_id);
1372  }
1373 
1375 
1376  /* would mark display buffers as invalid */
1377  RE_SetActiveRenderView(re, rv->name);
1378  re->display_update(re->duh, re->result, NULL);
1379  }
1380 
1381  MEM_freeN(ibuf_arr);
1382 
1383  recurs_depth--;
1384 
1385  /* just in case this flag went missing at some point */
1386  re->r.scemode |= R_DOSEQ;
1387 
1388  /* set overall progress of sequence rendering */
1389  if (re->r.efra != re->r.sfra) {
1390  re->progress(re->prh, (float)(cfra - re->r.sfra) / (re->r.efra - re->r.sfra));
1391  }
1392  else {
1393  re->progress(re->prh, 1.0f);
1394  }
1395 }
1396 
1397 /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
1398 
1399 /* Render full pipeline, using render engine, sequencer and compositing nodes. */
1401 {
1402  bool render_seq = false;
1403 
1404  re->current_scene_update(re->suh, re->scene);
1405 
1407 
1409 
1410  /* ensure no images are in memory from previous animated sequences */
1412  SEQ_cache_cleanup(re->scene);
1413 
1414  if (RE_engine_render(re, true)) {
1415  /* in this case external render overrides all */
1416  }
1417  else if (RE_seq_render_active(re->scene, &re->r)) {
1418  /* NOTE: do_render_sequencer() frees rect32 when sequencer returns float images. */
1419  if (!re->test_break(re->tbh)) {
1420  do_render_sequencer(re);
1421  render_seq = true;
1422  }
1423 
1424  re->stats_draw(re->sdh, &re->i);
1425  re->display_update(re->duh, re->result, NULL);
1426  }
1427  else {
1429  }
1430 
1432 
1433  re->stats_draw(re->sdh, &re->i);
1434 
1435  /* save render result stamp if needed */
1436  if (re->result != NULL) {
1437  /* sequence rendering should have taken care of that already */
1438  if (!(render_seq && (re->r.stamp & R_STAMP_STRIPMETA))) {
1439  Object *ob_camera_eval = DEG_get_evaluated_object(re->pipeline_depsgraph, RE_GetCamera(re));
1440  BKE_render_result_stamp_info(re->scene, ob_camera_eval, re->result, false);
1441  }
1442 
1443  /* stamp image info here */
1444  if ((re->r.stamp & R_STAMP_ALL) && (re->r.stamp & R_STAMP_DRAW)) {
1446  re->display_update(re->duh, re->result, NULL);
1447  }
1448  }
1449 }
1450 
1452  Object *camera_override,
1453  ReportList *reports)
1454 {
1455  if (scene->r.scemode & R_DOCOMP && scene->use_nodes) {
1457 
1458  while (node) {
1459  if (node->type == CMP_NODE_R_LAYERS && (node->flag & NODE_MUTED) == 0) {
1460  Scene *sce = node->id ? (Scene *)node->id : scene;
1461  if (sce->camera == NULL) {
1463  }
1464  if (sce->camera == NULL) {
1465  /* all render layers nodes need camera */
1466  BKE_reportf(reports,
1467  RPT_ERROR,
1468  "No camera found in scene \"%s\" (used in compositing of scene \"%s\")",
1469  sce->id.name + 2,
1470  scene->id.name + 2);
1471  return false;
1472  }
1473  }
1474  node = node->next;
1475  }
1476 
1477  return true;
1478  }
1479 
1480  const bool ok = (camera_override != NULL || scene->camera != NULL);
1481  if (!ok) {
1482  BKE_reportf(reports, RPT_ERROR, "No camera found in scene \"%s\"", scene->id.name + 2);
1483  }
1484 
1485  return ok;
1486 }
1487 
1489 {
1490  SceneRenderView *srv;
1491  bool active_view = false;
1492 
1493  if (camera == NULL || (scene->r.scemode & R_MULTIVIEW) == 0) {
1494  return true;
1495  }
1496 
1497  for (srv = scene->r.views.first; srv; srv = srv->next) {
1499  active_view = true;
1500 
1502  Object *view_camera;
1503  view_camera = BKE_camera_multiview_render(scene, camera, srv->name);
1504 
1505  if (view_camera == camera) {
1506  /* if the suffix is not in the camera, means we are using the fallback camera */
1507  if (!BLI_str_endswith(view_camera->id.name + 2, srv->suffix)) {
1508  BKE_reportf(reports,
1509  RPT_ERROR,
1510  "Camera \"%s\" is not a multi-view camera",
1511  camera->id.name + 2);
1512  return false;
1513  }
1514  }
1515  }
1516  }
1517  }
1518 
1519  if (!active_view) {
1520  BKE_reportf(reports, RPT_ERROR, "No active view found in scene \"%s\"", scene->id.name + 2);
1521  return false;
1522  }
1523 
1524  return true;
1525 }
1526 
1527 static int check_valid_camera(Scene *scene, Object *camera_override, ReportList *reports)
1528 {
1529  if (camera_override == NULL && scene->camera == NULL) {
1531  }
1532 
1533  if (!check_valid_camera_multiview(scene, scene->camera, reports)) {
1534  return false;
1535  }
1536 
1537  if (RE_seq_render_active(scene, &scene->r)) {
1538  if (scene->ed) {
1539  Sequence *seq = scene->ed->seqbase.first;
1540 
1541  while (seq) {
1542  if ((seq->type == SEQ_TYPE_SCENE) && ((seq->flag & SEQ_SCENE_STRIPS) == 0) &&
1543  (seq->scene != NULL)) {
1544  if (!seq->scene_camera) {
1545  if (!seq->scene->camera &&
1547  /* camera could be unneeded due to composite nodes */
1548  Object *override = (seq->scene == scene) ? camera_override : NULL;
1549 
1550  if (!check_valid_compositing_camera(seq->scene, override, reports)) {
1551  return false;
1552  }
1553  }
1554  }
1555  else if (!check_valid_camera_multiview(seq->scene, seq->scene_camera, reports)) {
1556  return false;
1557  }
1558  }
1559 
1560  seq = seq->next;
1561  }
1562  }
1563  }
1564  else if (!check_valid_compositing_camera(scene, camera_override, reports)) {
1565  return false;
1566  }
1567 
1568  return true;
1569 }
1570 
1572 {
1573  bNode *node;
1574 
1575  for (node = ntree->nodes.first; node; node = node->next) {
1577  return true;
1578  }
1579  if (ELEM(node->type, NODE_GROUP, NODE_CUSTOM_GROUP)) {
1580  if (node->id) {
1582  return true;
1583  }
1584  }
1585  }
1586  }
1587 
1588  return false;
1589 }
1590 
1592 {
1594 }
1595 
1597  ViewLayer *single_layer,
1598  Object *camera_override,
1599  ReportList *reports)
1600 {
1601  const int scemode = scene->r.scemode;
1602 
1603  if (scene->r.mode & R_BORDER) {
1604  if (scene->r.border.xmax <= scene->r.border.xmin ||
1605  scene->r.border.ymax <= scene->r.border.ymin) {
1606  BKE_report(reports, RPT_ERROR, "No border area selected");
1607  return 0;
1608  }
1609  }
1610 
1611  if (RE_seq_render_active(scene, &scene->r)) {
1612  /* Sequencer */
1613  if (scene->r.mode & R_BORDER) {
1614  BKE_report(reports, RPT_ERROR, "Border rendering is not supported by sequencer");
1615  return false;
1616  }
1617  }
1618  else if ((scemode & R_DOCOMP) && scene->use_nodes) {
1619  /* Compositor */
1620  if (!scene->nodetree) {
1621  BKE_report(reports, RPT_ERROR, "No node tree in scene");
1622  return 0;
1623  }
1624 
1626  BKE_report(reports, RPT_ERROR, "No render output node in scene");
1627  return 0;
1628  }
1629  }
1630  else {
1631  /* Regular Render */
1632  if (!render_scene_has_layers_to_render(scene, single_layer)) {
1633  BKE_report(reports, RPT_ERROR, "All render layers are disabled");
1634  return 0;
1635  }
1636  }
1637 
1638  /* check valid camera, without camera render is OK (compo, seq) */
1639  if (!check_valid_camera(scene, camera_override, reports)) {
1640  return 0;
1641  }
1642 
1643  return 1;
1644 }
1645 
1647  Scene *scene,
1648  ViewLayer *view_layer,
1649  int UNUSED(anim_init))
1650 {
1651  PTCacheBaker baker;
1652 
1653  memset(&baker, 0, sizeof(baker));
1654  baker.bmain = re->main;
1655  baker.scene = scene;
1656  baker.view_layer = view_layer;
1657  baker.depsgraph = BKE_scene_ensure_depsgraph(re->main, scene, view_layer);
1658  baker.bake = 0;
1659  baker.render = 1;
1660  baker.anim_init = 1;
1661  baker.quick_step = 1;
1662 
1663  BKE_ptcache_bake(&baker);
1664 }
1665 
1666 void RE_SetActiveRenderView(Render *re, const char *viewname)
1667 {
1668  BLI_strncpy(re->viewname, viewname, sizeof(re->viewname));
1669 }
1670 
1672 {
1673  return re->viewname;
1674 }
1675 
1676 /* evaluating scene options for general Blender render */
1678  const RenderData *rd,
1679  Main *bmain,
1680  Scene *scene,
1681  ViewLayer *single_layer,
1682  Object *camera_override,
1683  int anim,
1684  int anim_init)
1685 {
1686  int winx, winy;
1687  rcti disprect;
1688 
1689  /* r.xsch and r.ysch has the actual view window size
1690  * r.border is the clipping rect */
1691 
1692  /* calculate actual render result and display size */
1693  BKE_render_resolution(rd, false, &winx, &winy);
1694 
1695  /* We always render smaller part, inserting it in larger image is compositor business,
1696  * it uses 'disprect' for it. */
1697  if (scene->r.mode & R_BORDER) {
1698  disprect.xmin = rd->border.xmin * winx;
1699  disprect.xmax = rd->border.xmax * winx;
1700 
1701  disprect.ymin = rd->border.ymin * winy;
1702  disprect.ymax = rd->border.ymax * winy;
1703  }
1704  else {
1705  disprect.xmin = disprect.ymin = 0;
1706  disprect.xmax = winx;
1707  disprect.ymax = winy;
1708  }
1709 
1710  re->main = bmain;
1711  re->scene = scene;
1712  re->camera_override = camera_override;
1713  re->viewname[0] = '\0';
1714 
1715  /* not too nice, but it survives anim-border render */
1716  if (anim) {
1718  re->disprect = disprect;
1719  return 1;
1720  }
1721 
1722  /*
1723  * Disabled completely for now,
1724  * can be later set as render profile option
1725  * and default for background render.
1726  */
1727  if (0) {
1728  /* make sure dynamics are up to date */
1730  update_physics_cache(re, scene, view_layer, anim_init);
1731  }
1732 
1733  if (single_layer || scene->r.scemode & R_SINGLE_LAYER) {
1737  }
1738 
1739  RE_InitState(re, NULL, &scene->r, &scene->view_layers, single_layer, winx, winy, &disprect);
1740  if (!re->ok) { /* if an error was printed, abort */
1741  return 0;
1742  }
1743 
1744  /* initstate makes new result, have to send changed tags around */
1746 
1747  re->display_init(re->dih, re->result);
1748  re->display_clear(re->dch, re->result);
1749 
1750  return 1;
1751 }
1752 
1753 void RE_SetReports(Render *re, ReportList *reports)
1754 {
1755  re->reports = reports;
1756 }
1757 
1759 {
1760  Scene *scene = re->scene;
1763 }
1764 
1766 {
1767  Scene *scene = re->scene;
1768  ViewLayer *view_layer = BKE_view_layer_default_render(re->scene);
1769 
1770  re->pipeline_depsgraph = DEG_graph_new(re->main, scene, view_layer, DAG_EVAL_RENDER);
1771  DEG_debug_name_set(re->pipeline_depsgraph, "RENDER PIPELINE");
1772 
1773  /* Make sure there is a correct evaluated scene pointer. */
1775 
1776  /* Update immediately so we have proper evaluated scene. */
1778 
1780 }
1781 
1782 /* Free data only needed during rendering operation. */
1784 {
1785  if (re->engine && !RE_engine_use_persistent_data(re->engine)) {
1786  RE_engine_free(re->engine);
1787  re->engine = NULL;
1788  }
1789  if (re->pipeline_depsgraph != NULL) {
1791  re->pipeline_depsgraph = NULL;
1792  re->pipeline_scene_eval = NULL;
1793  }
1794  /* Destroy the opengl context in the correct thread. */
1796 
1797  /* In the case the engine did not mark tiles as finished (un-highlight, which could happen in the
1798  * case of cancelled render) ensure the storage is empty. */
1799  if (re->highlighted_tiles != NULL) {
1801 
1802  /* Rendering is supposed to be finished here, so no new tiles are expected to be written.
1803  * Only make it so possible read-only access to the highlighted tiles is thread-safe. */
1805 
1807  re->highlighted_tiles = NULL;
1808 
1810  }
1811 }
1812 
1814  Main *bmain,
1815  Scene *scene,
1816  ViewLayer *single_layer,
1817  Object *camera_override,
1818  const int frame,
1819  const float subframe,
1820  const bool write_still)
1821 {
1823 
1824  /* Ugly global still...
1825  * is to prevent preview events and signal subdivision-surface etc to make full resolution. */
1826  G.is_rendering = true;
1827 
1828  scene->r.cfra = frame;
1829  scene->r.subframe = subframe;
1830 
1831  if (render_init_from_main(re, &scene->r, bmain, scene, single_layer, camera_override, 0, 0)) {
1832  const RenderData rd = scene->r;
1834 
1836 
1838 
1840 
1841  if (write_still && !G.is_break) {
1843  /* operator checks this but in case its called from elsewhere */
1844  printf("Error: can't write single images with a movie format!\n");
1845  }
1846  else {
1847  char name[FILE_MAX];
1849  rd.pic,
1850  BKE_main_blendfile_path(bmain),
1851  scene->r.cfra,
1852  &rd.im_format,
1853  (rd.scemode & R_EXTENSION) != 0,
1854  false,
1855  NULL);
1856 
1857  /* reports only used for Movie */
1858  do_write_image_or_movie(re, bmain, scene, NULL, 0, name);
1859  }
1860  }
1861 
1862  /* keep after file save */
1864  if (write_still) {
1866  }
1867  }
1868 
1870  re->main,
1871  &scene->id,
1873 
1875 
1876  /* UGLY WARNING */
1877  G.is_rendering = false;
1878 }
1879 
1880 #ifdef WITH_FREESTYLE
1881 
1882 /* Not freestyle specific, currently only used by free-style. */
1883 static void change_renderdata_engine(Render *re, const char *new_engine)
1884 {
1885  if (!STREQ(re->r.engine, new_engine)) {
1886  if (re->engine) {
1887  RE_engine_free(re->engine);
1888  re->engine = NULL;
1889  }
1890  BLI_strncpy(re->r.engine, new_engine, sizeof(re->r.engine));
1891  }
1892 }
1893 
1894 static bool use_eevee_for_freestyle_render(Render *re)
1895 {
1897  return !(type->flag & RE_USE_CUSTOM_FREESTYLE);
1898 }
1899 
1900 void RE_RenderFreestyleStrokes(Render *re, Main *bmain, Scene *scene, int render)
1901 {
1902  re->result_ok = 0;
1903  if (render_init_from_main(re, &scene->r, bmain, scene, NULL, NULL, 0, 0)) {
1904  if (render) {
1905  char scene_engine[32];
1906  BLI_strncpy(scene_engine, re->r.engine, sizeof(scene_engine));
1907  if (use_eevee_for_freestyle_render(re)) {
1908  change_renderdata_engine(re, RE_engine_id_BLENDER_EEVEE);
1909  }
1910 
1911  RE_engine_render(re, false);
1912 
1913  change_renderdata_engine(re, scene_engine);
1914  }
1915  }
1916  re->result_ok = 1;
1917 }
1918 
1919 void RE_RenderFreestyleExternal(Render *re)
1920 {
1921  if (re->test_break(re->tbh)) {
1922  return;
1923  }
1924 
1926 
1927  LISTBASE_FOREACH (RenderView *, rv, &re->result->views) {
1928  RE_SetActiveRenderView(re, rv->name);
1929 
1930  ViewLayer *active_view_layer = BLI_findlink(&re->view_layers, re->active_view_layer);
1932 
1933  LISTBASE_FOREACH (ViewLayer *, view_layer, &re->view_layers) {
1934  if ((re->r.scemode & R_SINGLE_LAYER) && view_layer != active_view_layer) {
1935  continue;
1936  }
1937 
1938  if (FRS_is_freestyle_enabled(view_layer)) {
1939  FRS_do_stroke_rendering(re, view_layer);
1940  }
1941  }
1942 
1944  }
1945 }
1946 #endif
1947 
1950 /* -------------------------------------------------------------------- */
1955  RenderResult *rr,
1956  Scene *scene,
1957  RenderData *rd,
1958  bMovieHandle *mh,
1959  void **movie_ctx_arr,
1960  const int totvideos,
1961  bool preview)
1962 {
1963  bool ok = true;
1964 
1965  if (!rr) {
1966  return false;
1967  }
1968 
1969  ImageFormatData image_format;
1970  BKE_image_format_init_for_write(&image_format, scene, NULL);
1971 
1972  const bool is_mono = BLI_listbase_count_at_most(&rr->views, 2) < 2;
1973  const float dither = scene->r.dither_intensity;
1974 
1975  if (is_mono || (image_format.views_format == R_IMF_VIEWS_INDIVIDUAL)) {
1976  int view_id;
1977  for (view_id = 0; view_id < totvideos; view_id++) {
1978  const char *suffix = BKE_scene_multiview_view_id_suffix_get(&scene->r, view_id);
1979  ImBuf *ibuf = RE_render_result_rect_to_ibuf(rr, &rd->im_format, dither, view_id);
1980 
1981  IMB_colormanagement_imbuf_for_write(ibuf, true, false, &image_format);
1982 
1983  ok &= mh->append_movie(movie_ctx_arr[view_id],
1984  rd,
1985  preview ? scene->r.psfra : scene->r.sfra,
1986  scene->r.cfra,
1987  (int *)ibuf->rect,
1988  ibuf->x,
1989  ibuf->y,
1990  suffix,
1991  reports);
1992 
1993  /* imbuf knows which rects are not part of ibuf */
1994  IMB_freeImBuf(ibuf);
1995  }
1996  printf("Append frame %d\n", scene->r.cfra);
1997  }
1998  else { /* R_IMF_VIEWS_STEREO_3D */
1999  const char *names[2] = {STEREO_LEFT_NAME, STEREO_RIGHT_NAME};
2000  ImBuf *ibuf_arr[3] = {NULL};
2001  int i;
2002 
2003  BLI_assert((totvideos == 1) && (image_format.views_format == R_IMF_VIEWS_STEREO_3D));
2004 
2005  for (i = 0; i < 2; i++) {
2006  int view_id = BLI_findstringindex(&rr->views, names[i], offsetof(RenderView, name));
2007  ibuf_arr[i] = RE_render_result_rect_to_ibuf(rr, &rd->im_format, dither, view_id);
2008 
2009  IMB_colormanagement_imbuf_for_write(ibuf_arr[i], true, false, &image_format);
2010  }
2011 
2012  ibuf_arr[2] = IMB_stereo3d_ImBuf(&image_format, ibuf_arr[0], ibuf_arr[1]);
2013 
2014  ok = mh->append_movie(movie_ctx_arr[0],
2015  rd,
2016  preview ? scene->r.psfra : scene->r.sfra,
2017  scene->r.cfra,
2018  (int *)ibuf_arr[2]->rect,
2019  ibuf_arr[2]->x,
2020  ibuf_arr[2]->y,
2021  "",
2022  reports);
2023 
2024  for (i = 0; i < 3; i++) {
2025  /* imbuf knows which rects are not part of ibuf */
2026  IMB_freeImBuf(ibuf_arr[i]);
2027  }
2028  }
2029 
2030  BKE_image_format_free(&image_format);
2031 
2032  return ok;
2033 }
2034 
2036  Main *bmain,
2037  Scene *scene,
2038  bMovieHandle *mh,
2039  const int totvideos,
2040  const char *name_override)
2041 {
2042  char name[FILE_MAX];
2043  RenderResult rres;
2044  double render_time;
2045  bool ok = true;
2046  RenderEngineType *re_type = RE_engines_find(re->r.engine);
2047 
2048  /* Only disable file writing if postprocessing is also disabled. */
2049  const bool do_write_file = !(re_type->flag & RE_USE_NO_IMAGE_SAVE) ||
2050  (re_type->flag & RE_USE_POSTPROCESS);
2051 
2052  if (do_write_file) {
2053  RE_AcquireResultImageViews(re, &rres);
2054 
2055  /* write movie or image */
2058  re->reports, &rres, scene, &re->r, mh, re->movie_ctx_arr, totvideos, false);
2059  }
2060  else {
2061  if (name_override) {
2062  BLI_strncpy(name, name_override, sizeof(name));
2063  }
2064  else {
2066  scene->r.pic,
2067  BKE_main_blendfile_path(bmain),
2068  scene->r.cfra,
2069  &scene->r.im_format,
2070  (scene->r.scemode & R_EXTENSION) != 0,
2071  true,
2072  NULL);
2073  }
2074 
2075  /* write images as individual images or stereo */
2076  ok = BKE_image_render_write(re->reports, &rres, scene, true, name);
2077  }
2078 
2079  RE_ReleaseResultImageViews(re, &rres);
2080  }
2081 
2082  render_time = re->i.lastframetime;
2084 
2086  printf(" Time: %s", name);
2087 
2088  /* Flush stdout to be sure python callbacks are printing stuff after blender. */
2089  fflush(stdout);
2090 
2091  /* NOTE: using G_MAIN seems valid here???
2092  * Not sure it's actually even used anyway, we could as well pass NULL? */
2094 
2095  if (do_write_file) {
2096  BLI_timecode_string_from_time_simple(name, sizeof(name), re->i.lastframetime - render_time);
2097  printf(" (Saving: %s)\n", name);
2098  }
2099 
2100  fputc('\n', stdout);
2101  fflush(stdout);
2102 
2103  return ok;
2104 }
2105 
2106 static void get_videos_dimensions(const Render *re,
2107  const RenderData *rd,
2108  size_t *r_width,
2109  size_t *r_height)
2110 {
2111  size_t width, height;
2112  if (re->r.mode & R_BORDER) {
2113  if ((re->r.mode & R_CROP) == 0) {
2114  width = re->winx;
2115  height = re->winy;
2116  }
2117  else {
2118  width = re->rectx;
2119  height = re->recty;
2120  }
2121  }
2122  else {
2123  width = re->rectx;
2124  height = re->recty;
2125  }
2126 
2127  BKE_scene_multiview_videos_dimensions_get(rd, width, height, r_width, r_height);
2128 }
2129 
2130 static void re_movie_free_all(Render *re, bMovieHandle *mh, int totvideos)
2131 {
2132  int i;
2133 
2134  for (i = 0; i < totvideos; i++) {
2135  mh->end_movie(re->movie_ctx_arr[i]);
2136  mh->context_free(re->movie_ctx_arr[i]);
2137  }
2138 
2140 }
2141 
2143  Main *bmain,
2144  Scene *scene,
2145  ViewLayer *single_layer,
2146  Object *camera_override,
2147  int sfra,
2148  int efra,
2149  int tfra)
2150 {
2151  /* Call hooks before taking a copy of scene->r, so user can alter the render settings prior to
2152  * copying (e.g. alter the output path). */
2154 
2155  const RenderData rd = scene->r;
2156  bMovieHandle *mh = NULL;
2157  const int cfra_old = rd.cfra;
2158  const float subframe_old = rd.subframe;
2159  int nfra, totrendered = 0, totskipped = 0;
2160  const int totvideos = BKE_scene_multiview_num_videos_get(&rd);
2161  const bool is_movie = BKE_imtype_is_movie(rd.im_format.imtype);
2162  const bool is_multiview_name = ((rd.scemode & R_MULTIVIEW) != 0 &&
2164 
2165  /* do not fully call for each frame, it initializes & pops output window */
2166  if (!render_init_from_main(re, &rd, bmain, scene, single_layer, camera_override, 0, 1)) {
2167  return;
2168  }
2169 
2170  RenderEngineType *re_type = RE_engines_find(re->r.engine);
2171 
2172  /* Only disable file writing if postprocessing is also disabled. */
2173  const bool do_write_file = !(re_type->flag & RE_USE_NO_IMAGE_SAVE) ||
2174  (re_type->flag & RE_USE_POSTPROCESS);
2175 
2177 
2178  if (is_movie && do_write_file) {
2179  size_t width, height;
2180  int i;
2181  bool is_error = false;
2182 
2183  get_videos_dimensions(re, &rd, &width, &height);
2184 
2186  if (mh == NULL) {
2187  BKE_report(re->reports, RPT_ERROR, "Movie format unsupported");
2188  return;
2189  }
2190 
2191  re->movie_ctx_arr = MEM_mallocN(sizeof(void *) * totvideos, "Movies' Context");
2192 
2193  for (i = 0; i < totvideos; i++) {
2194  const char *suffix = BKE_scene_multiview_view_id_suffix_get(&re->r, i);
2195 
2196  re->movie_ctx_arr[i] = mh->context_create();
2197 
2198  if (!mh->start_movie(re->movie_ctx_arr[i],
2199  re->pipeline_scene_eval,
2200  &re->r,
2201  width,
2202  height,
2203  re->reports,
2204  false,
2205  suffix)) {
2206  is_error = true;
2207  break;
2208  }
2209  }
2210 
2211  if (is_error) {
2212  /* report is handled above */
2213  re_movie_free_all(re, mh, i + 1);
2215  return;
2216  }
2217  }
2218 
2219  /* Ugly global still... is to prevent renderwin events and signal subdivision-surface etc
2220  * to make full resolution is also set by caller renderwin.c */
2221  G.is_rendering = true;
2222 
2223  re->flag |= R_ANIMATION;
2224 
2225  {
2226  scene->r.subframe = 0.0f;
2227  for (nfra = sfra, scene->r.cfra = sfra; scene->r.cfra <= efra; scene->r.cfra++) {
2228  char name[FILE_MAX];
2229 
2230  /* A feedback loop exists here -- render initialization requires updated
2231  * render layers settings which could be animated, but scene evaluation for
2232  * the frame happens later because it depends on what layers are visible to
2233  * render engine.
2234  *
2235  * The idea here is to only evaluate animation data associated with the scene,
2236  * which will make sure render layer settings are up-to-date, initialize the
2237  * render database itself and then perform full scene update with only needed
2238  * layers.
2239  * -sergey-
2240  */
2241  {
2242  float ctime = BKE_scene_ctime_get(scene);
2244  const AnimationEvalContext anim_eval_context = BKE_animsys_eval_context_construct(
2245  re->pipeline_depsgraph, ctime);
2246  BKE_animsys_evaluate_animdata(&scene->id, adt, &anim_eval_context, ADT_RECALC_ALL, false);
2247  }
2248 
2250 
2251  /* Only border now, TODO(ton): camera lens. */
2252  render_init_from_main(re, &rd, bmain, scene, single_layer, camera_override, 1, 0);
2253 
2254  if (nfra != scene->r.cfra) {
2255  /* Skip this frame, but could update for physics and particles system. */
2256  continue;
2257  }
2258 
2259  nfra += tfra;
2260 
2261  /* Touch/NoOverwrite options are only valid for image's */
2262  if (is_movie == false && do_write_file) {
2263  if (rd.mode & (R_NO_OVERWRITE | R_TOUCH)) {
2265  rd.pic,
2266  BKE_main_blendfile_path(bmain),
2267  scene->r.cfra,
2268  &rd.im_format,
2269  (rd.scemode & R_EXTENSION) != 0,
2270  true,
2271  NULL);
2272  }
2273 
2274  if (rd.mode & R_NO_OVERWRITE) {
2275  if (!is_multiview_name) {
2276  if (BLI_exists(name)) {
2277  printf("skipping existing frame \"%s\"\n", name);
2278  totskipped++;
2279  continue;
2280  }
2281  }
2282  else {
2283  SceneRenderView *srv;
2284  bool is_skip = false;
2285  char filepath[FILE_MAX];
2286 
2287  for (srv = scene->r.views.first; srv; srv = srv->next) {
2289  continue;
2290  }
2291 
2292  BKE_scene_multiview_filepath_get(srv, name, filepath);
2293 
2294  if (BLI_exists(filepath)) {
2295  is_skip = true;
2296  printf("skipping existing frame \"%s\" for view \"%s\"\n", filepath, srv->name);
2297  }
2298  }
2299 
2300  if (is_skip) {
2301  totskipped++;
2302  continue;
2303  }
2304  }
2305  }
2306 
2307  if (rd.mode & R_TOUCH) {
2308  if (!is_multiview_name) {
2309  if (!BLI_exists(name)) {
2310  BLI_make_existing_file(name); /* makes the dir if its not there */
2312  }
2313  }
2314  else {
2315  SceneRenderView *srv;
2316  char filepath[FILE_MAX];
2317 
2318  for (srv = scene->r.views.first; srv; srv = srv->next) {
2320  continue;
2321  }
2322 
2323  BKE_scene_multiview_filepath_get(srv, name, filepath);
2324 
2325  if (!BLI_exists(filepath)) {
2326  BLI_make_existing_file(filepath); /* makes the dir if its not there */
2327  BLI_file_touch(filepath);
2328  }
2329  }
2330  }
2331  }
2332  }
2333 
2334  re->r.cfra = scene->r.cfra; /* weak.... */
2335  re->r.subframe = scene->r.subframe;
2336 
2337  /* run callbacks before rendering, before the scene is updated */
2339 
2341  totrendered++;
2342 
2343  if (re->test_break(re->tbh) == 0) {
2344  if (!G.is_break) {
2345  if (!do_write_image_or_movie(re, bmain, scene, mh, totvideos, NULL)) {
2346  G.is_break = true;
2347  }
2348  }
2349  }
2350  else {
2351  G.is_break = true;
2352  }
2353 
2354  if (G.is_break == true) {
2355  /* remove touched file */
2356  if (is_movie == false && do_write_file) {
2357  if (rd.mode & R_TOUCH) {
2358  if (!is_multiview_name) {
2359  if ((BLI_file_size(name) == 0)) {
2360  /* BLI_exists(name) is implicit */
2361  BLI_delete(name, false, false);
2362  }
2363  }
2364  else {
2365  SceneRenderView *srv;
2366  char filepath[FILE_MAX];
2367 
2368  for (srv = scene->r.views.first; srv; srv = srv->next) {
2370  continue;
2371  }
2372 
2373  BKE_scene_multiview_filepath_get(srv, name, filepath);
2374 
2375  if ((BLI_file_size(filepath) == 0)) {
2376  /* BLI_exists(filepath) is implicit */
2377  BLI_delete(filepath, false, false);
2378  }
2379  }
2380  }
2381  }
2382  }
2383 
2384  break;
2385  }
2386 
2387  if (G.is_break == false) {
2388  /* keep after file save */
2391  }
2392  }
2393  }
2394 
2395  /* end movie */
2396  if (is_movie && do_write_file) {
2397  re_movie_free_all(re, mh, totvideos);
2398  }
2399 
2400  if (totskipped && totrendered == 0) {
2401  BKE_report(re->reports, RPT_INFO, "No frames rendered, skipped to not overwrite");
2402  }
2403 
2404  scene->r.cfra = cfra_old;
2405  scene->r.subframe = subframe_old;
2406 
2407  re->flag &= ~R_ANIMATION;
2408 
2410  re->main,
2411  &scene->id,
2414 
2416 
2417  /* UGLY WARNING */
2418  G.is_rendering = false;
2419 }
2420 
2421 void RE_PreviewRender(Render *re, Main *bmain, Scene *sce)
2422 {
2423  Object *camera;
2424  int winx, winy;
2425 
2426  BKE_render_resolution(&sce->r, false, &winx, &winy);
2427 
2428  RE_InitState(re, NULL, &sce->r, &sce->view_layers, NULL, winx, winy, NULL);
2429 
2430  re->main = bmain;
2431  re->scene = sce;
2432 
2433  camera = RE_GetCamera(re);
2434  RE_SetCamera(re, camera);
2435 
2436  RE_engine_render(re, false);
2437 
2438  /* No persistent data for preview render. */
2439  if (re->engine) {
2440  RE_engine_free(re->engine);
2441  re->engine = NULL;
2442  }
2443 }
2444 
2445 /* NOTE: repeated win/disprect calc... solve that nicer, also in compo. */
2446 
2448 {
2449  Render *re;
2450  int winx, winy;
2451  bool success;
2452  rcti disprect;
2453 
2454  /* calculate actual render result and display size */
2455  BKE_render_resolution(&scene->r, false, &winx, &winy);
2456 
2457  /* only in movie case we render smaller part */
2458  if (scene->r.mode & R_BORDER) {
2459  disprect.xmin = scene->r.border.xmin * winx;
2460  disprect.xmax = scene->r.border.xmax * winx;
2461 
2462  disprect.ymin = scene->r.border.ymin * winy;
2463  disprect.ymax = scene->r.border.ymax * winy;
2464  }
2465  else {
2466  disprect.xmin = disprect.ymin = 0;
2467  disprect.xmax = winx;
2468  disprect.ymax = winy;
2469  }
2470 
2471  if (scenode) {
2472  scene = scenode;
2473  }
2474 
2475  /* get render: it can be called from UI with draw callbacks */
2476  re = RE_GetSceneRender(scene);
2477  if (re == NULL) {
2478  re = RE_NewSceneRender(scene);
2479  }
2480  RE_InitState(re, NULL, &scene->r, &scene->view_layers, NULL, winx, winy, &disprect);
2481  re->scene = scene;
2482 
2484  success = render_result_exr_file_cache_read(re);
2486 
2488 
2489  return success;
2490 }
2491 
2493  RenderLayer *layer, ReportList *reports, const char *filepath, int x, int y)
2494 {
2495  /* OCIO_TODO: assume layer was saved in default color space */
2496  ImBuf *ibuf = IMB_loadiffname(filepath, IB_rect, NULL);
2497  RenderPass *rpass = NULL;
2498 
2499  /* multiview: since the API takes no 'view', we use the first combined pass found */
2500  for (rpass = layer->passes.first; rpass; rpass = rpass->next) {
2501  if (STREQ(rpass->name, RE_PASSNAME_COMBINED)) {
2502  break;
2503  }
2504  }
2505 
2506  if (rpass == NULL) {
2507  BKE_reportf(reports,
2508  RPT_ERROR,
2509  "%s: no Combined pass found in the render layer '%s'",
2510  __func__,
2511  filepath);
2512  }
2513 
2514  if (ibuf && (ibuf->rect || ibuf->rect_float)) {
2515  if (ibuf->x == layer->rectx && ibuf->y == layer->recty) {
2516  if (ibuf->rect_float == NULL) {
2517  IMB_float_from_rect(ibuf);
2518  }
2519 
2520  memcpy(rpass->rect, ibuf->rect_float, sizeof(float[4]) * layer->rectx * layer->recty);
2521  }
2522  else {
2523  if ((ibuf->x - x >= layer->rectx) && (ibuf->y - y >= layer->recty)) {
2524  ImBuf *ibuf_clip;
2525 
2526  if (ibuf->rect_float == NULL) {
2527  IMB_float_from_rect(ibuf);
2528  }
2529 
2530  ibuf_clip = IMB_allocImBuf(layer->rectx, layer->recty, 32, IB_rectfloat);
2531  if (ibuf_clip) {
2532  IMB_rectcpy(ibuf_clip, ibuf, 0, 0, x, y, layer->rectx, layer->recty);
2533 
2534  memcpy(
2535  rpass->rect, ibuf_clip->rect_float, sizeof(float[4]) * layer->rectx * layer->recty);
2536  IMB_freeImBuf(ibuf_clip);
2537  }
2538  else {
2539  BKE_reportf(
2540  reports, RPT_ERROR, "%s: failed to allocate clip buffer '%s'", __func__, filepath);
2541  }
2542  }
2543  else {
2544  BKE_reportf(reports,
2545  RPT_ERROR,
2546  "%s: incorrect dimensions for partial copy '%s'",
2547  __func__,
2548  filepath);
2549  }
2550  }
2551 
2552  IMB_freeImBuf(ibuf);
2553  }
2554  else {
2555  BKE_reportf(reports, RPT_ERROR, "%s: failed to load '%s'", __func__, filepath);
2556  }
2557 }
2558 
2559 void RE_result_load_from_file(RenderResult *result, ReportList *reports, const char *filepath)
2560 {
2561  if (!render_result_exr_file_read_path(result, NULL, filepath)) {
2562  BKE_reportf(reports, RPT_ERROR, "%s: failed to load '%s'", __func__, filepath);
2563  return;
2564  }
2565 }
2566 
2568 {
2569  switch (BLI_listbase_count_at_most(&rr->layers, 2)) {
2570  case 0:
2571  return false;
2572  case 1:
2573  return (((RenderLayer *)rr->layers.first)->name[0] != '\0');
2574  default:
2575  return true;
2576  }
2577  return false;
2578 }
2579 
2581 {
2582  LISTBASE_FOREACH (RenderPass *, rp, &rl->passes) {
2583  if (!STREQ(rp->name, "Combined")) {
2584  return true;
2585  }
2586  }
2587 
2588  return false;
2589 }
2590 
2591 RenderPass *RE_pass_find_by_name(RenderLayer *rl, const char *name, const char *viewname)
2592 {
2593  RenderPass *rp = NULL;
2594 
2595  for (rp = rl->passes.last; rp; rp = rp->prev) {
2596  if (STREQ(rp->name, name)) {
2597  if (viewname == NULL || viewname[0] == '\0') {
2598  break;
2599  }
2600  if (STREQ(rp->view, viewname)) {
2601  break;
2602  }
2603  }
2604  }
2605  return rp;
2606 }
2607 
2608 RenderPass *RE_pass_find_by_type(RenderLayer *rl, int passtype, const char *viewname)
2609 {
2610 #define CHECK_PASS(NAME) \
2611  if (passtype == SCE_PASS_##NAME) { \
2612  return RE_pass_find_by_name(rl, RE_PASSNAME_##NAME, viewname); \
2613  } \
2614  ((void)0)
2615 
2616  CHECK_PASS(COMBINED);
2617  CHECK_PASS(Z);
2618  CHECK_PASS(VECTOR);
2619  CHECK_PASS(NORMAL);
2620  CHECK_PASS(UV);
2621  CHECK_PASS(EMIT);
2622  CHECK_PASS(SHADOW);
2623  CHECK_PASS(AO);
2624  CHECK_PASS(ENVIRONMENT);
2625  CHECK_PASS(INDEXOB);
2626  CHECK_PASS(INDEXMA);
2627  CHECK_PASS(MIST);
2628  CHECK_PASS(DIFFUSE_DIRECT);
2629  CHECK_PASS(DIFFUSE_INDIRECT);
2630  CHECK_PASS(DIFFUSE_COLOR);
2631  CHECK_PASS(GLOSSY_DIRECT);
2632  CHECK_PASS(GLOSSY_INDIRECT);
2633  CHECK_PASS(GLOSSY_COLOR);
2634  CHECK_PASS(TRANSM_DIRECT);
2635  CHECK_PASS(TRANSM_INDIRECT);
2636  CHECK_PASS(TRANSM_COLOR);
2637  CHECK_PASS(SUBSURFACE_DIRECT);
2638  CHECK_PASS(SUBSURFACE_INDIRECT);
2639  CHECK_PASS(SUBSURFACE_COLOR);
2640 
2641 #undef CHECK_PASS
2642 
2643  return NULL;
2644 }
2645 
2646 RenderPass *RE_create_gp_pass(RenderResult *rr, const char *layername, const char *viewname)
2647 {
2648  RenderLayer *rl = BLI_findstring(&rr->layers, layername, offsetof(RenderLayer, name));
2649  /* only create render layer if not exist */
2650  if (!rl) {
2651  rl = MEM_callocN(sizeof(RenderLayer), layername);
2652  BLI_addtail(&rr->layers, rl);
2653  BLI_strncpy(rl->name, layername, sizeof(rl->name));
2654  rl->layflag = SCE_LAY_SOLID;
2656  rl->rectx = rr->rectx;
2657  rl->recty = rr->recty;
2658  }
2659 
2660  /* Clear previous pass if exist or the new image will be over previous one. */
2662  if (rp) {
2663  if (rp->rect) {
2664  MEM_freeN(rp->rect);
2665  }
2666  BLI_freelinkN(&rl->passes, rp);
2667  }
2668  /* create a totally new pass */
2669  return render_layer_add_pass(rr, rl, 4, RE_PASSNAME_COMBINED, viewname, "RGBA", true);
2670 }
2671 
2674 /* -------------------------------------------------------------------- */
2679 {
2680  /* override not showing object when duplis are used with particles */
2681  if (ob->transflag & OB_DUPLIPARTS) {
2682  /* pass */ /* let particle system(s) handle showing vs. not showing */
2683  }
2684  else if (ob->transflag & OB_DUPLI) {
2685  return false;
2686  }
2687  return true;
2688 }
2689 
2691 {
2692  re->r.threads = BKE_render_num_threads(&re->r);
2693 }
2694 
struct AnimData * BKE_animdata_from_id(const struct ID *id)
AnimationEvalContext BKE_animsys_eval_context_construct(struct Depsgraph *depsgraph, float eval_time)
Definition: anim_sys.c:761
@ ADT_RECALC_ALL
Definition: BKE_animsys.h:291
void BKE_animsys_evaluate_animdata(struct ID *id, struct AnimData *adt, const struct AnimationEvalContext *anim_eval_context, eAnimData_Recalc recalc, bool flush_to_original)
void BKE_callback_exec_null(struct Main *bmain, eCbEvent evt)
Definition: callbacks.c:41
eCbEvent
Definition: BKE_callbacks.h:74
@ BKE_CB_EVT_RENDER_COMPLETE
Definition: BKE_callbacks.h:82
@ BKE_CB_EVT_RENDER_POST
Definition: BKE_callbacks.h:78
@ BKE_CB_EVT_RENDER_STATS
Definition: BKE_callbacks.h:80
@ BKE_CB_EVT_RENDER_PRE
Definition: BKE_callbacks.h:77
@ BKE_CB_EVT_RENDER_WRITE
Definition: BKE_callbacks.h:79
@ BKE_CB_EVT_RENDER_INIT
Definition: BKE_callbacks.h:81
@ BKE_CB_EVT_RENDER_CANCEL
Definition: BKE_callbacks.h:83
void BKE_callback_exec_id(struct Main *bmain, struct ID *id, eCbEvent evt)
Definition: callbacks.c:46
Camera data-block and utility functions.
struct Object * BKE_camera_multiview_render(const struct Scene *scene, struct Object *camera, const char *viewname)
void BKE_curvemapping_free_data(struct CurveMapping *cumap)
Definition: colortools.c:83
void BKE_curvemapping_copy_data(struct CurveMapping *target, const struct CurveMapping *cumap)
#define G_MAIN
Definition: BKE_global.h:267
struct StampData * BKE_stamp_data_copy(const struct StampData *stamp_data)
void BKE_stamp_info_from_imbuf(struct RenderResult *rr, struct ImBuf *ibuf)
void BKE_render_result_stamp_info(struct Scene *scene, struct Object *camera, struct RenderResult *rr, bool allocate_only)
void BKE_image_stamp_buf(struct Scene *scene, struct Object *camera, const struct StampData *stamp_data_template, unsigned char *rect, float *rectf, int width, int height, int channels)
void BKE_image_all_free_anim_ibufs(struct Main *bmain, int cfra)
void BKE_image_format_free(struct ImageFormatData *imf)
Definition: image_format.cc:52
void BKE_image_path_from_imformat(char *string, const char *base, const char *relbase, int frame, const struct ImageFormatData *im_format, bool use_ext, bool use_frames, const char *suffix)
bool BKE_imtype_is_movie(char imtype)
void BKE_image_format_init_for_write(struct ImageFormatData *imf, const struct Scene *scene_src, const struct ImageFormatData *imf_src)
bool BKE_image_render_write(struct ReportList *reports, struct RenderResult *rr, const struct Scene *scene, const bool stamp, const char *filepath_basis)
struct Object * BKE_view_layer_camera_find(struct ViewLayer *view_layer)
Definition: layer.c:311
struct ViewLayer * BKE_view_layer_context_active_PLACEHOLDER(const struct Scene *scene)
struct ViewLayer * BKE_view_layer_default_render(const struct Scene *scene)
const char * BKE_main_blendfile_path(const struct Main *bmain) ATTR_NONNULL()
#define CMP_NODE_COMPOSITE
Definition: BKE_node.h:1217
#define NODE_CUSTOM_GROUP
Definition: BKE_node.h:989
void ntreeFreeCache(struct bNodeTree *ntree)
Definition: node.cc:3130
#define CMP_NODE_OUTPUT_FILE
Definition: BKE_node.h:1218
#define CMP_NODE_R_LAYERS
Definition: BKE_node.h:1216
General operations, lookup, etc. for blender objects.
void BKE_ptcache_bake(struct PTCacheBaker *baker)
Definition: pointcache.c:3156
void BKE_reportf(ReportList *reports, eReportType type, const char *format,...) ATTR_PRINTF_FORMAT(3
void BKE_report(ReportList *reports, eReportType type, const char *message)
Definition: report.c:83
int BKE_scene_multiview_num_videos_get(const struct RenderData *rd)
void BKE_scene_update_sound(struct Depsgraph *depsgraph, struct Main *bmain)
Definition: scene.cc:2539
bool BKE_scene_multiview_is_render_view_active(const struct RenderData *rd, const struct SceneRenderView *srv)
float BKE_scene_frame_get(const struct Scene *scene)
void BKE_render_resolution(const struct RenderData *r, const bool use_crop, int *r_width, int *r_height)
Definition: scene.cc:2960
int BKE_render_num_threads(const struct RenderData *r)
bool BKE_scene_camera_switch_update(struct Scene *scene)
Definition: scene.cc:2295
float BKE_scene_ctime_get(const struct Scene *scene)
int BKE_scene_multiview_num_views_get(const struct RenderData *rd)
int BKE_scene_multiview_view_id_get(const struct RenderData *rd, const char *viewname)
struct Depsgraph * BKE_scene_ensure_depsgraph(struct Main *bmain, struct Scene *scene, struct ViewLayer *view_layer)
Definition: scene.cc:3456
const char * BKE_scene_multiview_view_id_suffix_get(const struct RenderData *rd, int view_id)
void BKE_scene_multiview_filepath_get(const struct SceneRenderView *srv, const char *filepath, char *r_filepath)
void BKE_scene_multiview_videos_dimensions_get(const struct RenderData *rd, size_t width, size_t height, size_t *r_width, size_t *r_height)
void BKE_sound_reset_scene_specs(struct Scene *scene)
bMovieHandle * BKE_movie_handle_get(char imtype)
Definition: writeavi.c:98
#define BLI_assert(a)
Definition: BLI_assert.h:46
File and directory operations.
int BLI_exists(const char *path) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL()
Definition: storage.c:314
bool BLI_file_touch(const char *file) ATTR_NONNULL()
Definition: fileops.c:192
int BLI_delete(const char *file, bool dir, bool recursive) ATTR_NONNULL()
Definition: fileops.c:934
size_t BLI_file_size(const char *path) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL()
Definition: storage.c:187
struct GSet GSet
Definition: BLI_ghash.h:340
bool BLI_gset_haskey(const GSet *gs, const void *key) ATTR_WARN_UNUSED_RESULT
Definition: BLI_ghash.c:1007
GSet * BLI_gset_ptr_new(const char *info)
void BLI_gset_free(GSet *gs, GSetKeyFreeFP keyfreefp)
Definition: BLI_ghash.c:1037
bool BLI_gset_add(GSet *gs, void *key)
Definition: BLI_ghash.c:969
#define LISTBASE_FOREACH(type, var, list)
Definition: BLI_listbase.h:336
void BLI_freelinkN(struct ListBase *listbase, void *vlink) ATTR_NONNULL(1)
Definition: listbase.c:239
void void void void void BLI_duplicatelist(struct ListBase *dst, const struct ListBase *src) ATTR_NONNULL(1
int BLI_listbase_count_at_most(const struct ListBase *listbase, int count_max) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
void void BLI_freelistN(struct ListBase *listbase) ATTR_NONNULL(1)
Definition: listbase.c:466
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_findindex(const struct ListBase *listbase, const void *vlink) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
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)
bool BLI_make_existing_file(const char *name)
Definition: path_util.c:1197
#define FILE_MAX
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
bool BLI_str_endswith(const char *__restrict str, const char *__restrict end) ATTR_NONNULL()
Definition: string.c:887
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
void BLI_rw_mutex_end(ThreadRWMutex *mutex)
Definition: threads.cc:503
void BLI_mutex_end(ThreadMutex *mutex)
Definition: threads.cc:388
#define THREAD_LOCK_READ
Definition: BLI_threads.h:120
void BLI_mutex_init(ThreadMutex *mutex)
Definition: threads.cc:368
#define THREAD_LOCK_WRITE
Definition: BLI_threads.h:121
#define BLI_MUTEX_INITIALIZER
Definition: BLI_threads.h:83
void BLI_rw_mutex_lock(ThreadRWMutex *mutex, int mode)
Definition: threads.cc:488
void BLI_mutex_lock(ThreadMutex *mutex)
Definition: threads.cc:373
void BLI_mutex_unlock(ThreadMutex *mutex)
Definition: threads.cc:378
void BLI_rw_mutex_init(ThreadRWMutex *mutex)
Definition: threads.cc:483
void BLI_rw_mutex_unlock(ThreadRWMutex *mutex)
Definition: threads.cc:498
pthread_mutex_t ThreadMutex
Definition: BLI_threads.h:82
size_t BLI_timecode_string_from_time_simple(char *str, size_t maxncpy, double time_seconds) ATTR_NONNULL()
Definition: timecode.c:169
#define SWAP(type, a, b)
#define STREQLEN(a, b, n)
#define UNUSED(x)
#define ELEM(...)
#define STREQ(a, b)
#define TIP_(msgid)
ThreadMutex mutex
Depsgraph * DEG_graph_new(struct Main *bmain, struct Scene *scene, struct ViewLayer *view_layer, eEvaluationMode mode)
Definition: depsgraph.cc:267
@ DAG_EVAL_RENDER
Definition: DEG_depsgraph.h:46
void DEG_graph_free(Depsgraph *graph)
Definition: depsgraph.cc:295
void DEG_evaluate_on_framechange(Depsgraph *graph, float frame)
void DEG_graph_build_for_render_pipeline(struct Depsgraph *graph)
void DEG_debug_name_set(struct Depsgraph *depsgraph, const char *name)
struct Object * DEG_get_evaluated_object(const struct Depsgraph *depsgraph, struct Object *object)
struct Scene * DEG_get_evaluated_scene(const struct Depsgraph *graph)
#define ID_IS_LINKED(_id)
Definition: DNA_ID.h:566
Object groups, one object can be in many groups at once.
@ VIEW_LAYER_RENDER
#define NODE_MUTED
Object is a sort of wrapper for general info.
@ OB_DUPLI
@ OB_DUPLIPARTS
#define R_STAMP_ALL
#define RE_PASSNAME_COMBINED
#define STEREO_LEFT_NAME
#define R_EXTENSION
#define R_SINGLE_LAYER
#define R_BORDER
#define R_MULTIVIEW
#define R_CROP
#define R_NO_OVERWRITE
#define R_DOCOMP
#define R_DOSEQ
#define R_BUTS_PREVIEW
#define R_EXR_CACHE_FILE
#define R_STAMP_DRAW
#define SCE_LAY_SOLID
#define R_STAMP_STRIPMETA
#define R_TOUCH
#define RE_PASSNAME_Z
#define R_EDGE_FRS
#define STEREO_RIGHT_NAME
@ R_IMF_VIEWS_STEREO_3D
@ R_IMF_VIEWS_INDIVIDUAL
@ SCE_PASS_COMBINED
@ SCE_VIEWS_FORMAT_MULTIVIEW
@ SEQ_TYPE_SOUND_RAM
@ SEQ_TYPE_SCENE
@ SEQ_SCENE_STRIPS
@ SEQ_RENDER_SIZE_SCENE
void FRS_init_stroke_renderer(struct Render *re)
void FRS_exit(void)
void FRS_end_stroke_rendering(struct Render *re)
void FRS_begin_stroke_rendering(struct Render *re)
int FRS_is_freestyle_enabled(struct ViewLayer *view_layer)
void FRS_do_stroke_rendering(struct Render *re, struct ViewLayer *view_layer)
void GPU_context_discard(GPUContext *)
Definition: gpu_context.cc:110
GPUContext * GPU_context_create(void *ghost_window)
Definition: gpu_context.cc:93
void GPU_context_active_set(GPUContext *)
Definition: gpu_context.cc:127
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei height
_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
_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 type
_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 GLsizei width
#define Z
Definition: GeomUtils.cpp:201
struct ImBuf * IMB_colormanagement_imbuf_for_write(struct ImBuf *ibuf, bool save_as_render, bool allocate_result, const struct ImageFormatData *image_format)
void IMB_float_from_rect(struct ImBuf *ibuf)
Definition: divers.c:805
struct ImBuf * IMB_stereo3d_ImBuf(const struct ImageFormatData *im_format, struct ImBuf *ibuf_left, struct ImBuf *ibuf_right)
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)
struct ImBuf * IMB_loadiffname(const char *filepath, int flags, char colorspace[IM_MAX_SPACE])
Definition: readimage.c:209
void IMB_rectcpy(struct ImBuf *dbuf, const struct ImBuf *sbuf, int destx, int desty, int srcx, int srcy, int width, int height)
Contains defines and structs used throughout the imbuf module.
@ IB_rectfloat
@ IB_rect
void IMB_metadata_copy(struct ImBuf *dimb, struct ImBuf *simb)
Definition: metadata.c:64
Read Guarded memory(de)allocation.
#define MEM_SAFE_FREE(v)
NODE_GROUP
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
in reality light always falls off quadratically Particle Retrieve the data of the particle that spawned the object for example to give variation to multiple instances of an object Point Retrieve information about points in a point cloud Retrieve the edges of an object as it appears to Cycles topology will always appear triangulated Convert a blackbody temperature to an RGB value Normal Generate a perturbed normal from an RGB normal map image Typically used for faking highly detailed surfaces Generate an OSL shader from a file or text data block Image Sample an image file as a texture Sky Generate a procedural sky texture Noise Generate fractal Perlin noise Wave Generate procedural bands or rings with noise Voronoi Generate Worley noise based on the distance to random points Typically used to generate textures such as or biological cells Brick Generate a procedural texture producing bricks Texture Retrieve multiple types of texture coordinates nTypically used as inputs for texture nodes Vector Convert a or normal between camera
Platform independent time functions.
#define RE_USE_CUSTOM_FREESTYLE
Definition: RE_engine.h:53
#define RE_USE_NO_IMAGE_SAVE
Definition: RE_engine.h:54
#define RE_ENGINE_RENDERING
Definition: RE_engine.h:62
#define RE_USE_POSTPROCESS
Definition: RE_engine.h:46
#define RE_MAXNAME
Definition: RE_pipeline.h:36
volatile int lock
OperationNode * node
StackEntry * from
Scene scene
bNodeTree * ntree
RenderEngineType * RE_engines_find(const char *idname)
Definition: engine.c:98
bool RE_engine_use_persistent_data(RenderEngine *engine)
Definition: engine.c:695
bool RE_engine_render(Render *re, bool do_all)
Definition: engine.c:988
void RE_engine_free(RenderEngine *engine)
Definition: engine.c:164
#define str(s)
void IMB_freeImBuf(ImBuf *UNUSED(ibuf))
void SEQ_cache_cleanup(Scene *scene)
Definition: image_cache.c:602
void RE_SetCamera(Render *re, const Object *cam_ob)
Definition: initrender.c:161
struct Object * RE_GetCamera(Render *re)
Definition: initrender.c:150
static char ** names
Definition: makesdna.c:65
size_t(* MEM_get_peak_memory)(void)
Definition: mallocn.c:48
void(* MEM_freeN)(void *vmemh)
Definition: mallocn.c:27
void(* MEM_reset_peak_memory)(void)
Definition: mallocn.c:47
size_t(* MEM_get_memory_in_use)(void)
Definition: mallocn.c:45
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 size_t mem_in_use
#define G(x, y, z)
static const pxr::TfToken out("out", pxr::TfToken::Immortal)
static const pxr::TfToken preview("preview", pxr::TfToken::Immortal)
void ntreeCompositTagRender(Scene *scene)
void ntreeCompositExecTree(Scene *scene, bNodeTree *ntree, RenderData *rd, int rendering, int do_preview, const char *view_name)
bool RE_HasSingleLayer(Render *re)
Definition: pipeline.c:253
void RE_ReleaseResultImageViews(Render *re, RenderResult *rr)
Definition: pipeline.c:418
Render * RE_GetRender(const char *name)
Definition: pipeline.c:300
void RE_stats_draw_cb(Render *re, void *handle, void(*f)(void *handle, RenderStats *rs))
Definition: pipeline.c:874
RenderPass * RE_pass_find_by_type(RenderLayer *rl, int passtype, const char *viewname)
Definition: pipeline.c:2608
static void re_free_persistent_data(Render *re)
Definition: pipeline.c:651
RenderPass * RE_create_gp_pass(RenderResult *rr, const char *layername, const char *viewname)
Definition: pipeline.c:2646
void RE_FreeRender(Render *re)
Definition: pipeline.c:584
static void do_render_engine(Render *re)
Definition: pipeline.c:1014
RenderPass * RE_pass_find_by_name(RenderLayer *rl, const char *name, const char *viewname)
Definition: pipeline.c:2591
RenderResult * RE_AcquireResultRead(Render *re)
Definition: pipeline.c:314
void RE_ReleaseResultImage(Render *re)
Definition: pipeline.c:474
void RE_progress_cb(Render *re, void *handle, void(*f)(void *handle, float))
Definition: pipeline.c:879
void RE_PreviewRender(Render *re, Main *bmain, Scene *sce)
Definition: pipeline.c:2421
static int render_init_from_main(Render *re, const RenderData *rd, Main *bmain, Scene *scene, ViewLayer *single_layer, Object *camera_override, int anim, int anim_init)
Definition: pipeline.c:1677
static void update_physics_cache(Render *re, Scene *scene, ViewLayer *view_layer, int UNUSED(anim_init))
Definition: pipeline.c:1646
static void do_render_compositor_scenes(Render *re)
Definition: pipeline.c:1101
static void do_render_compositor_scene(Render *re, Scene *sce, int cfra)
Definition: pipeline.c:1036
static void re_movie_free_all(Render *re, bMovieHandle *mh, int totvideos)
Definition: pipeline.c:2130
int RE_seq_render_active(Scene *scene, RenderData *rd)
Definition: pipeline.c:1264
bool RE_WriteRenderViewsMovie(ReportList *reports, RenderResult *rr, Scene *scene, RenderData *rd, bMovieHandle *mh, void **movie_ctx_arr, const int totvideos, bool preview)
Definition: pipeline.c:1954
static void render_callback_exec_null(Render *re, Main *bmain, eCbEvent evt)
Definition: pipeline.c:134
static void stats_background(void *UNUSED(arg), RenderStats *rs)
Definition: pipeline.c:186
static void result_nothing(void *UNUSED(arg), RenderResult *UNUSED(rr))
Definition: pipeline.c:164
void RE_current_scene_update_cb(Render *re, void *handle, void(*f)(void *handle, Scene *scene))
Definition: pipeline.c:869
void * RE_gpu_context_get(Render *re)
Definition: pipeline.c:932
void * RE_gl_context_get(Render *re)
Definition: pipeline.c:927
Render * RE_GetSceneRender(const Scene *scene)
Definition: pipeline.c:551
static bool do_write_image_or_movie(Render *re, Main *bmain, Scene *scene, bMovieHandle *mh, const int totvideos, const char *name_override)
Definition: pipeline.c:2035
void render_copy_renderdata(RenderData *to, RenderData *from)
Definition: pipeline.c:717
ListBase renderlist
Definition: pipeline.c:125
void RE_FreePersistentData(const Scene *scene)
Definition: pipeline.c:660
static int compositor_needs_render(Scene *sce, int this_scene)
Definition: pipeline.c:1075
static bool check_valid_camera_multiview(Scene *scene, Object *camera, ReportList *reports)
Definition: pipeline.c:1488
static void stats_nothing(void *UNUSED(arg), RenderStats *UNUSED(rs))
Definition: pipeline.c:175
static struct @1170 RenderGlobal
static void render_update_depsgraph(Render *re)
Definition: pipeline.c:1758
void RE_AcquireResultImage(Render *re, RenderResult *rr, const int view_id)
Definition: pipeline.c:428
static int check_compositor_output(Scene *scene)
Definition: pipeline.c:1591
void RE_layer_load_from_file(RenderLayer *layer, ReportList *reports, const char *filepath, int x, int y)
Definition: pipeline.c:2492
#define MAX_SCENE_RENDER_NAME
Definition: pipeline.c:539
void RE_ClearResult(Render *re)
Definition: pipeline.c:335
void RE_SwapResult(Render *re, RenderResult **rr)
Definition: pipeline.c:343
Render * RE_NewRender(const char *name)
Definition: pipeline.c:516
void RE_FreeRenderResult(RenderResult *rr)
Definition: pipeline.c:233
static void current_scene_nothing(void *UNUSED(arg), Scene *UNUSED(scene))
Definition: pipeline.c:172
static void render_pipeline_free(Render *re)
Definition: pipeline.c:1783
bool RE_passes_have_name(struct RenderLayer *rl)
Definition: pipeline.c:2580
RenderLayer * render_get_active_layer(Render *re, RenderResult *rr)
Definition: pipeline.c:264
void RE_FreeAllPersistentData(void)
Definition: pipeline.c:639
static void float_nothing(void *UNUSED(arg), float UNUSED(val))
Definition: pipeline.c:178
void RE_InitRenderCB(Render *re)
Definition: pipeline.c:565
void RE_RenderFrame(Render *re, Main *bmain, Scene *scene, ViewLayer *single_layer, Object *camera_override, const int frame, const float subframe, const bool write_still)
Definition: pipeline.c:1813
static int check_valid_camera(Scene *scene, Object *camera_override, ReportList *reports)
Definition: pipeline.c:1527
void render_update_anim_renderdata(Render *re, RenderData *rd, ListBase *render_layers)
Definition: pipeline.c:831
void RE_gl_context_destroy(Render *re)
Definition: pipeline.c:911
static void scene_render_name_get(const Scene *scene, const size_t max_size, char *render_name)
Definition: pipeline.c:541
static void render_result_uncrop(Render *re)
Definition: pipeline.c:962
RenderLayer * RE_GetRenderLayer(RenderResult *rr, const char *name)
Definition: pipeline.c:244
Render * RE_NewSceneRender(const Scene *scene)
Definition: pipeline.c:558
static void render_result_disprect_to_full_resolution(Render *re)
Definition: pipeline.c:953
static void do_render_sequencer(Render *re)
Definition: pipeline.c:1285
void RE_InitState(Render *re, Render *source, RenderData *rd, ListBase *render_layers, ViewLayer *single_layer, int winx, int winy, rcti *disprect)
Definition: pipeline.c:728
void RE_ReleaseResult(Render *re)
Definition: pipeline.c:351
static void render_compositor_stats(void *arg, const char *str)
Definition: pipeline.c:1142
float * RE_RenderLayerGetPass(RenderLayer *rl, const char *name, const char *viewname)
Definition: pipeline.c:238
void RE_RenderAnim(Render *re, Main *bmain, Scene *scene, ViewLayer *single_layer, Object *camera_override, int sfra, int efra, int tfra)
Definition: pipeline.c:2142
static void do_render_full_pipeline(Render *re)
Definition: pipeline.c:1400
static bool node_tree_has_compositor_output(bNodeTree *ntree)
Definition: pipeline.c:1571
const char * RE_GetActiveRenderView(Render *re)
Definition: pipeline.c:1671
RenderResult * RE_MultilayerConvert(void *exrhandle, const char *colorspace, bool predivide, int rectx, int recty)
Definition: pipeline.c:258
static void do_render_compositor(Render *re)
Definition: pipeline.c:1154
RenderResult * RE_AcquireResultWrite(Render *re)
Definition: pipeline.c:324
Scene * RE_GetScene(Render *re)
Definition: pipeline.c:358
static void re_init_resolution(Render *re, Render *source, int winx, int winy, rcti *disprect)
Definition: pipeline.c:682
bool RE_layers_have_name(struct RenderResult *rr)
Definition: pipeline.c:2567
void RE_display_clear_cb(Render *re, void *handle, void(*f)(void *handle, RenderResult *rr))
Definition: pipeline.c:857
bool RE_allow_render_generic_object(Object *ob)
Definition: pipeline.c:2678
void RE_gl_context_create(Render *re)
Definition: pipeline.c:903
void RE_result_load_from_file(RenderResult *result, ReportList *reports, const char *filepath)
Definition: pipeline.c:2559
void RE_display_update_cb(Render *re, void *handle, void(*f)(void *handle, RenderResult *rr, rcti *rect))
Definition: pipeline.c:862
void RE_test_break_cb(Render *re, void *handle, int(*f)(void *handle))
Definition: pipeline.c:891
static void get_videos_dimensions(const Render *re, const RenderData *rd, size_t *r_width, size_t *r_height)
Definition: pipeline.c:2106
static void result_rcti_nothing(void *UNUSED(arg), RenderResult *UNUSED(rr), struct rcti *UNUSED(rect))
Definition: pipeline.c:167
static void renderresult_stampinfo(Render *re)
Definition: pipeline.c:1239
static void render_init_depsgraph(Render *re)
Definition: pipeline.c:1765
void RE_AcquiredResultGet32(Render *re, RenderResult *result, unsigned int *rect, const int view_id)
Definition: pipeline.c:497
bool RE_is_rendering_allowed(Scene *scene, ViewLayer *single_layer, Object *camera_override, ReportList *reports)
Definition: pipeline.c:1596
void RE_draw_lock_cb(Render *re, void *handle, void(*f)(void *handle, bool lock))
Definition: pipeline.c:885
void RE_SetReports(Render *re, ReportList *reports)
Definition: pipeline.c:1753
void RE_FreeAllRender(void)
Definition: pipeline.c:614
void RE_AcquireResultImageViews(Render *re, RenderResult *rr)
Definition: pipeline.c:373
static int default_break(void *UNUSED(arg))
Definition: pipeline.c:181
static bool render_scene_has_layers_to_render(Scene *scene, ViewLayer *single_layer)
Definition: pipeline.c:279
bool RE_ReadRenderResult(Scene *scene, Scene *scenode)
Definition: pipeline.c:2447
void RE_SetScene(Render *re, Scene *sce)
Definition: pipeline.c:366
#define CHECK_PASS(NAME)
void RE_ResultGet32(Render *re, unsigned int *rect)
Definition: pipeline.c:481
static void render_callback_exec_id(Render *re, Main *bmain, ID *id, eCbEvent evt)
Definition: pipeline.c:142
static bool check_valid_compositing_camera(Scene *scene, Object *camera_override, ReportList *reports)
Definition: pipeline.c:1451
void RE_FreeAllRenderResults(void)
Definition: pipeline.c:626
void RE_SetActiveRenderView(Render *re, const char *viewname)
Definition: pipeline.c:1666
RenderStats * RE_GetStats(Render *re)
Definition: pipeline.c:511
void RE_init_threadcount(Render *re)
Definition: pipeline.c:2690
void RE_display_init_cb(Render *re, void *handle, void(*f)(void *handle, RenderResult *rr))
Definition: pipeline.c:852
ImBuf * SEQ_render_give_ibuf(const SeqRenderData *context, float timeline_frame, int chanshown)
Definition: render.c:1925
void SEQ_render_new_render_data(Main *bmain, struct Depsgraph *depsgraph, Scene *scene, int rectx, int recty, int preview_render_size, int for_render, SeqRenderData *r_context)
Definition: render.c:205
void SEQ_render_imbuf_from_sequencer_space(Scene *scene, ImBuf *ibuf)
Definition: render.c:167
void render_result_single_layer_end(Render *re)
RenderView * RE_RenderViewGetById(RenderResult *rr, const int view_id)
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)
RenderPass * render_layer_add_pass(RenderResult *rr, RenderLayer *rl, int channels, const char *name, const char *viewname, const char *chan_id, const bool allocate)
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)
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)
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)
void render_result_single_layer_begin(Render *re)
void render_result_views_shallowcopy(RenderResult *dst, RenderResult *src)
#define RR_ALL_VIEWS
Definition: render_result.h:13
#define RR_ALL_LAYERS
Definition: render_result.h:12
#define R_ANIMATION
Definition: render_types.h:133
const char * RE_engine_id_BLENDER_EEVEE
Definition: scene.cc:1695
static bool is_movie(wmDrag *drag)
_W64 unsigned int uintptr_t
Definition: stdint.h:119
void SEQ_relations_free_imbuf(Scene *scene, ListBase *seqbase, bool for_render)
ListBase seqbase
Definition: DNA_ID.h:368
struct Library * lib
Definition: DNA_ID.h:372
char name[66]
Definition: DNA_ID.h:378
struct IDProperty * metadata
float dither
char name[IMB_FILENAME_SIZE]
unsigned int * rect
float * rect_float
ID id
Definition: DNA_ID.h:458
void * last
Definition: DNA_listBase.h:31
void * first
Definition: DNA_listBase.h:31
Definition: BKE_main.h:121
short transflag
struct Scene * scene
struct Main * bmain
struct Depsgraph * depsgraph
struct ViewLayer * view_layer
struct CurveMapping mblur_shutter_curve
char engine[32]
struct ImageFormatData im_format
char pic[1024]
float dither_intensity
ListBase views
int line_thickness_mode
short views_format
float unit_line_thickness
ListBase passes
Definition: RE_pipeline.h:95
char name[RE_MAXNAME]
Definition: RE_pipeline.h:87
struct RenderLayer * next
Definition: RE_pipeline.h:84
char name[64]
Definition: RE_pipeline.h:65
char view[64]
Definition: RE_pipeline.h:71
float * rect
Definition: RE_pipeline.h:67
struct RenderPass * prev
Definition: RE_pipeline.h:63
struct RenderPass * next
Definition: RE_pipeline.h:63
ListBase views
Definition: RE_pipeline.h:125
ListBase layers
Definition: RE_pipeline.h:122
float * rectz
Definition: RE_pipeline.h:114
struct StampData * stamp_data
Definition: RE_pipeline.h:141
float * rectf
Definition: RE_pipeline.h:112
RenderLayer * renlay
Definition: RE_pipeline.h:129
double starttime
Definition: RE_pipeline.h:149
double lastframetime
Definition: RE_pipeline.h:149
const char * infostr
Definition: RE_pipeline.h:150
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
ThreadMutex engine_draw_mutex
Definition: render_types.h:60
void(* current_scene_update)(void *handle, struct Scene *scene)
Definition: render_types.h:105
int recty
Definition: render_types.h:70
void * dch
Definition: render_types.h:102
void * sdh
Definition: render_types.h:109
void(* progress)(void *handle, float i)
Definition: render_types.h:110
Scene * pipeline_scene_eval
Definition: render_types.h:96
void * duh
Definition: render_types.h:104
void * prh
Definition: render_types.h:111
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
struct RenderEngine * engine
Definition: render_types.h:91
struct Main * main
Definition: render_types.h:80
void * dih
Definition: render_types.h:100
short ok
Definition: render_types.h:46
int active_view_layer
Definition: render_types.h:84
struct GSet * highlighted_tiles
Definition: render_types.h:88
void * dlh
Definition: render_types.h:114
Scene * scene
Definition: render_types.h:81
int rectx
Definition: render_types.h:70
struct Depsgraph * pipeline_depsgraph
Definition: render_types.h:95
void(* display_update)(void *handle, RenderResult *rr, rcti *rect)
Definition: render_types.h:103
short result_ok
Definition: render_types.h:46
short flag
Definition: render_types.h:46
ThreadRWMutex resultmutex
Definition: render_types.h:57
char viewname[MAX_NAME]
Definition: render_types.h:123
struct Render * next
Definition: render_types.h:41
RenderStats i
Definition: render_types.h:118
void * tbh
Definition: render_types.h:116
void ** movie_ctx_arr
Definition: render_types.h:122
int winx
Definition: render_types.h:65
void(* display_init)(void *handle, RenderResult *rr)
Definition: render_types.h:99
void(* draw_lock)(void *handle, bool lock)
Definition: render_types.h:113
void(* stats_draw)(void *handle, RenderStats *ri)
Definition: render_types.h:108
void(* display_clear)(void *handle, RenderResult *rr)
Definition: render_types.h:101
int(* test_break)(void *handle)
Definition: render_types.h:115
ThreadMutex highlighted_tiles_mutex
Definition: render_types.h:87
void * suh
Definition: render_types.h:106
struct ReportList * reports
Definition: render_types.h:120
rcti disprect
Definition: render_types.h:66
struct Object * camera_override
Definition: render_types.h:85
void * gl_context
Definition: render_types.h:126
ListBase view_layers
Definition: render_types.h:83
char name[RE_MAXNAME]
Definition: render_types.h:42
void * gpu_context
Definition: render_types.h:127
struct SceneRenderView * next
struct bNodeTree * nodetree
ColorManagedViewSettings view_settings
struct Editing * ed
struct RenderData r
ListBase view_layers
struct Object * camera
char use_nodes
ColorManagedDisplaySettings display_settings
struct Scene * scene
struct Object * scene_camera
struct Sequence * next
struct ViewLayer * next
char name[64]
Definition: IMB_anim.h:71
void(* end_movie)(void *context_v)
Definition: BKE_writeavi.h:38
int(* start_movie)(void *context_v, const struct Scene *scene, struct RenderData *rd, int rectx, int recty, struct ReportList *reports, bool preview, const char *suffix)
Definition: BKE_writeavi.h:21
void(* context_free)(void *context_v)
Definition: BKE_writeavi.h:47
void *(* context_create)(void)
Definition: BKE_writeavi.h:46
int(* append_movie)(void *context_v, struct RenderData *rd, int start_frame, int frame, int *pixels, int rectx, int recty, const char *suffix, struct ReportList *reports)
Definition: BKE_writeavi.h:29
void(* progress)(void *, float progress)
int(* test_break)(void *)
void(* stats_draw)(void *, const char *str)
ListBase nodes
float xmax
Definition: DNA_vec_types.h:69
float xmin
Definition: DNA_vec_types.h:69
float ymax
Definition: DNA_vec_types.h:70
float ymin
Definition: DNA_vec_types.h:70
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
void RE_point_density_fix_linking(void)
double PIL_check_seconds_timer(void)
Definition: time.c:64
void * WM_opengl_context_create(void)
Definition: wm_window.c:2353
void wm_window_reset_drawable(void)
Definition: wm_window.c:1049
void WM_opengl_context_activate(void *context)
Definition: wm_window.c:2380
void WM_opengl_context_dispose(void *context)
Definition: wm_window.c:2374