Blender V4.5
render_context.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2023 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
5#include <memory>
6#include <string>
7
8#include "BLI_assert.h"
9#include "BLI_listbase.h"
10#include "BLI_map.hh"
11#include "BLI_math_vector.h"
13#include "BLI_string.h"
14#include "BLI_utildefines.h"
15
16#include "MEM_guardedalloc.h"
17
18#include "IMB_imbuf.hh"
19#include "IMB_imbuf_types.hh"
20
21#include "DNA_scene_types.h"
23
24#include "BKE_image.hh"
25#include "BKE_image_save.hh"
26#include "BKE_report.hh"
27#include "BKE_scene.hh"
28
29#include "RE_pipeline.h"
30
31#include "COM_render_context.hh"
32
33namespace blender::compositor {
34
35/* ------------------------------------------------------------------------------------------------
36 * File Output
37 */
38
39FileOutput::FileOutput(const std::string &path,
41 int2 size,
42 bool save_as_render)
43 : path_(path), format_(format), save_as_render_(save_as_render)
44{
45 render_result_ = MEM_callocN<RenderResult>("Temporary Render Result For File Output");
46
47 render_result_->rectx = size.x;
48 render_result_->recty = size.y;
49
50 /* NOTE: set dummy values which will won't be used unless overwritten.
51 * When `save_as_render` is set, this is overwritten by the scenes PPM setting.
52 * We *could* support setting the DPI in the file output node too. */
53 render_result_->ppm[0] = 0.0;
54 render_result_->ppm[1] = 0.0;
55
56 /* File outputs are always single layer, as images are actually stored in passes on that single
57 * layer. Create a single unnamed layer to add the passes to. A single unnamed layer is treated
58 * by the EXR writer as a special case where the channel names take the form:
59 * <pass-name>.<view-name>.<channel-id>
60 * Otherwise, the layer name would have preceded in the pass name in yet another section. */
61 RenderLayer *render_layer = MEM_callocN<RenderLayer>("Render Layer For File Output.");
62 BLI_addtail(&render_result_->layers, render_layer);
63 render_layer->name[0] = '\0';
64
65 /* File outputs do not support previews. */
66 format_.flag &= ~R_IMF_FLAG_PREVIEW_JPG;
67}
68
70{
71 RE_FreeRenderResult(render_result_);
72}
73
74void FileOutput::add_view(const char *view_name)
75{
76 /* Empty views can only be added for EXR images. */
78
79 RenderView *render_view = MEM_callocN<RenderView>("Render View For File Output.");
80 BLI_addtail(&render_result_->views, render_view);
81 STRNCPY(render_view->name, view_name);
82}
83
84void FileOutput::add_view(const char *view_name, int channels, float *buffer)
85{
86 RenderView *render_view = MEM_callocN<RenderView>("Render View For File Output.");
87 BLI_addtail(&render_result_->views, render_view);
88 STRNCPY(render_view->name, view_name);
89
90 render_view->ibuf = IMB_allocImBuf(
91 render_result_->rectx, render_result_->recty, channels * 8, 0);
92 render_view->ibuf->channels = channels;
93 IMB_assign_float_buffer(render_view->ibuf, buffer, IB_TAKE_OWNERSHIP);
94}
95
96void FileOutput::add_pass(const char *pass_name,
97 const char *view_name,
98 const char *channels,
99 float *buffer)
100{
101 /* Passes can only be added for EXR images. */
103
104 RenderLayer *render_layer = static_cast<RenderLayer *>(render_result_->layers.first);
105 RenderPass *render_pass = MEM_callocN<RenderPass>("Render Pass For File Output.");
106 BLI_addtail(&render_layer->passes, render_pass);
107 STRNCPY(render_pass->name, pass_name);
108 STRNCPY(render_pass->view, view_name);
109 STRNCPY(render_pass->chan_id, channels);
110
111 const int channels_count = BLI_strnlen(channels, 4);
112 render_pass->rectx = render_result_->rectx;
113 render_pass->recty = render_result_->recty;
114 render_pass->channels = channels_count;
115
116 render_pass->ibuf = IMB_allocImBuf(
117 render_result_->rectx, render_result_->recty, channels_count * 8, 0);
118 render_pass->ibuf->channels = channels_count;
119 copy_v2_v2_db(render_pass->ibuf->ppm, render_result_->ppm);
120 IMB_assign_float_buffer(render_pass->ibuf, buffer, IB_TAKE_OWNERSHIP);
121}
122
123void FileOutput::add_meta_data(std::string key, std::string value)
124{
125 meta_data_.add(key, value);
126}
127
129{
132
133 /* Add scene stamp data as meta data as well as the custom meta data. */
134 BKE_render_result_stamp_info(scene, nullptr, render_result_, false);
135 for (const auto &field : meta_data_.items()) {
136 BKE_render_result_stamp_data(render_result_, field.key.c_str(), field.value.c_str());
137 }
138
139 /* NOTE: without this the file will be written without any density information.
140 * So always write this. */
141 if (save_as_render_ || true) {
142 BKE_scene_ppm_get(&scene->r, render_result_->ppm);
143 }
144
146 &reports, render_result_, scene, true, path_.c_str(), &format_, save_as_render_);
147
149}
150
151/* ------------------------------------------------------------------------------------------------
152 * Render Context
153 */
154
157 int2 size,
158 bool save_as_render)
159{
160 return *file_outputs_.lookup_or_add_cb(
161 path, [&]() { return std::make_unique<FileOutput>(path, format, size, save_as_render); });
162}
163
165{
166 for (std::unique_ptr<FileOutput> &file_output : file_outputs_.values()) {
167 file_output->save(scene);
168 }
169}
170
171} // namespace blender::compositor
void BKE_render_result_stamp_info(Scene *scene, Object *camera, RenderResult *rr, bool allocate_only)
void BKE_render_result_stamp_data(RenderResult *rr, const char *key, const char *value)
bool BKE_image_render_write(ReportList *reports, RenderResult *rr, const Scene *scene, const bool stamp, const char *filepath_basis, const ImageFormatData *format=nullptr, bool save_as_render=true)
void BKE_reports_free(ReportList *reports)
Definition report.cc:70
void BKE_reports_init(ReportList *reports, int flag)
Definition report.cc:55
void BKE_scene_ppm_get(const RenderData *rd, double r_ppm[2])
Definition scene.cc:3245
#define BLI_assert(a)
Definition BLI_assert.h:46
void BLI_addtail(ListBase *listbase, void *vlink) ATTR_NONNULL(1)
Definition listbase.cc:111
MINLINE void copy_v2_v2_db(double r[2], const double a[2])
int char char int int int int size_t BLI_strnlen(const char *str, size_t maxlen) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
Definition string.cc:923
char * STRNCPY(char(&dst)[N], const char *src)
Definition BLI_string.h:688
#define ELEM(...)
@ R_IMF_FLAG_PREVIEW_JPG
@ R_IMF_IMTYPE_OPENEXR
@ R_IMF_IMTYPE_MULTILAYER
void IMB_assign_float_buffer(ImBuf *ibuf, float *buffer_data, ImBufOwnership ownership)
ImBuf * IMB_allocImBuf(unsigned int x, unsigned int y, unsigned char planes, unsigned int flags)
@ IB_TAKE_OWNERSHIP
Read Guarded memory(de)allocation.
ReportList * reports
Definition WM_types.hh:1025
static DBVT_INLINE btScalar size(const btDbvtVolume &a)
Definition btDbvt.cpp:52
void add_view(const char *view_name)
FileOutput(const std::string &path, const ImageFormatData &format, int2 size, bool save_as_render)
void add_pass(const char *pass_name, const char *view_name, const char *channels, float *buffer)
void add_meta_data(std::string key, std::string value)
FileOutput & get_file_output(std::string path, ImageFormatData format, int2 size, bool save_as_render)
format
void * MEM_callocN(size_t len, const char *str)
Definition mallocn.cc:118
VecBase< int32_t, 2 > int2
void RE_FreeRenderResult(RenderResult *rr)
double ppm[2]
ListBase passes
Definition RE_pipeline.h:89
char name[RE_MAXNAME]
Definition RE_pipeline.h:81
struct ImBuf * ibuf
Definition RE_pipeline.h:60
char chan_id[8]
Definition RE_pipeline.h:51
char name[64]
Definition RE_pipeline.h:50
char view[64]
Definition RE_pipeline.h:65
struct ImBuf * ibuf
Definition RE_pipeline.h:44
char name[64]
Definition RE_pipeline.h:39
struct RenderData r