Blender V4.3
image_vdb.cpp
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2011-2022 Blender Foundation
2 *
3 * SPDX-License-Identifier: Apache-2.0 */
4
5#include "scene/image_vdb.h"
6
7#include "util/log.h"
8#include "util/openvdb.h"
9
10#ifdef WITH_OPENVDB
11# include <openvdb/tools/Dense.h>
12#endif
13#ifdef WITH_NANOVDB
14# define NANOVDB_USE_OPENVDB
15# include <nanovdb/util/OpenToNanoVDB.h>
16#endif
17
19
20#ifdef WITH_OPENVDB
21struct NumChannelsOp {
22 int num_channels = 0;
23
24 template<typename GridType, typename FloatGridType, typename FloatDataType, int channels>
25 bool operator()(const openvdb::GridBase::ConstPtr &)
26 {
27 num_channels = channels;
28 return true;
29 }
30};
31
32struct ToDenseOp {
33 openvdb::CoordBBox bbox;
34 void *pixels;
35
36 template<typename GridType, typename FloatGridType, typename FloatDataType, int channels>
37 bool operator()(const openvdb::GridBase::ConstPtr &grid)
38 {
39 openvdb::tools::Dense<FloatDataType, openvdb::tools::LayoutXYZ> dense(bbox,
40 (FloatDataType *)pixels);
41 openvdb::tools::copyToDense(*openvdb::gridConstPtrCast<GridType>(grid), dense);
42 return true;
43 }
44};
45
46# ifdef WITH_NANOVDB
47struct ToNanoOp {
48 nanovdb::GridHandle<> nanogrid;
49 int precision;
50
51 template<typename GridType, typename FloatGridType, typename FloatDataType, int channels>
52 bool operator()(const openvdb::GridBase::ConstPtr &grid)
53 {
54 if constexpr (!std::is_same_v<GridType, openvdb::MaskGrid>) {
55 try {
56# if NANOVDB_MAJOR_VERSION_NUMBER > 32 || \
57 (NANOVDB_MAJOR_VERSION_NUMBER == 32 && NANOVDB_MINOR_VERSION_NUMBER >= 6)
58 /* OpenVDB 11. */
59 if constexpr (std::is_same_v<FloatGridType, openvdb::FloatGrid>) {
60 openvdb::FloatGrid floatgrid(*openvdb::gridConstPtrCast<GridType>(grid));
61 if (precision == 0) {
62 nanogrid = nanovdb::createNanoGrid<openvdb::FloatGrid, nanovdb::FpN>(floatgrid);
63 }
64 else if (precision == 16) {
65 nanogrid = nanovdb::createNanoGrid<openvdb::FloatGrid, nanovdb::Fp16>(floatgrid);
66 }
67 else {
68 nanogrid = nanovdb::createNanoGrid<openvdb::FloatGrid, float>(floatgrid);
69 }
70 }
71 else if constexpr (std::is_same_v<FloatGridType, openvdb::Vec3fGrid>) {
72 openvdb::Vec3fGrid floatgrid(*openvdb::gridConstPtrCast<GridType>(grid));
73 nanogrid = nanovdb::createNanoGrid<openvdb::Vec3fGrid, nanovdb::Vec3f>(
74 floatgrid, nanovdb::StatsMode::Disable);
75 }
76# else
77 /* OpenVDB 10. */
78 if constexpr (std::is_same_v<FloatGridType, openvdb::FloatGrid>) {
79 openvdb::FloatGrid floatgrid(*openvdb::gridConstPtrCast<GridType>(grid));
80 if (precision == 0) {
81 nanogrid =
82 nanovdb::openToNanoVDB<nanovdb::HostBuffer, openvdb::FloatTree, nanovdb::FpN>(
83 floatgrid);
84 }
85 else if (precision == 16) {
86 nanogrid =
87 nanovdb::openToNanoVDB<nanovdb::HostBuffer, openvdb::FloatTree, nanovdb::Fp16>(
88 floatgrid);
89 }
90 else {
91 nanogrid = nanovdb::openToNanoVDB(floatgrid);
92 }
93 }
94 else if constexpr (std::is_same_v<FloatGridType, openvdb::Vec3fGrid>) {
95 openvdb::Vec3fGrid floatgrid(*openvdb::gridConstPtrCast<GridType>(grid));
96 nanogrid = nanovdb::openToNanoVDB(floatgrid);
97 }
98# endif
99 }
100 catch (const std::exception &e) {
101 VLOG_WARNING << "Error converting OpenVDB to NanoVDB grid: " << e.what();
102 }
103 catch (...) {
104 VLOG_WARNING << "Error converting OpenVDB to NanoVDB grid: Unknown error";
105 }
106 return true;
107 }
108 else {
109 return false;
110 }
111 }
112};
113# endif
114
115VDBImageLoader::VDBImageLoader(openvdb::GridBase::ConstPtr grid_, const string &grid_name)
116 : grid_name(grid_name), grid(grid_)
117{
118}
119#endif
120
121VDBImageLoader::VDBImageLoader(const string &grid_name) : grid_name(grid_name) {}
122
124
126{
127#ifdef WITH_OPENVDB
128 if (!grid) {
129 return false;
130 }
131
132 /* Get number of channels from type. */
133 NumChannelsOp op;
134 if (!openvdb::grid_type_operation(grid, op)) {
135 return false;
136 }
137
138 metadata.channels = op.num_channels;
139
140 /* Set data type. */
141# ifdef WITH_NANOVDB
142 if (features.has_nanovdb) {
143 /* NanoVDB expects no inactive leaf nodes. */
144# if 0
145 openvdb::FloatGrid &pruned_grid = *openvdb::gridPtrCast<openvdb::FloatGrid>(grid);
146 openvdb::tools::pruneInactive(pruned_grid.tree());
147 nanogrid = nanovdb::openToNanoVDB(pruned_grid);
148# endif
149 ToNanoOp op;
150 op.precision = precision;
151 if (!openvdb::grid_type_operation(grid, op)) {
152 return false;
153 }
154 nanogrid = std::move(op.nanogrid);
155 }
156# endif
157
158 /* Set dimensions. */
159 bbox = grid->evalActiveVoxelBoundingBox();
160 if (bbox.empty()) {
161 return false;
162 }
163
164 openvdb::Coord dim = bbox.dim();
165 metadata.width = dim.x();
166 metadata.height = dim.y();
167 metadata.depth = dim.z();
168
169# ifdef WITH_NANOVDB
170 if (nanogrid) {
171 metadata.byte_size = nanogrid.size();
172 if (metadata.channels == 1) {
173 if (precision == 0) {
175 }
176 else if (precision == 16) {
178 }
179 else {
181 }
182 }
183 else {
185 }
186 }
187 else
188# endif
189 {
190 if (metadata.channels == 1) {
191 metadata.type = IMAGE_DATA_TYPE_FLOAT;
192 }
193 else {
194 metadata.type = IMAGE_DATA_TYPE_FLOAT4;
195 }
196 }
197
198 /* Set transform from object space to voxel index. */
199 openvdb::math::Mat4f grid_matrix = grid->transform().baseMap()->getAffineMap()->getMat4();
200 Transform index_to_object;
201 for (int col = 0; col < 4; col++) {
202 for (int row = 0; row < 3; row++) {
203 index_to_object[row][col] = (float)grid_matrix[col][row];
204 }
205 }
206
207 Transform texture_to_index;
208# ifdef WITH_NANOVDB
209 if (nanogrid) {
210 texture_to_index = transform_identity();
211 }
212 else
213# endif
214 {
215 openvdb::Coord min = bbox.min();
216 texture_to_index = transform_translate(min.x(), min.y(), min.z()) *
217 transform_scale(dim.x(), dim.y(), dim.z());
218 }
219
220 metadata.transform_3d = transform_inverse(index_to_object * texture_to_index);
221 metadata.use_transform_3d = true;
222
223# ifndef WITH_NANOVDB
224 (void)features;
225# endif
226 return true;
227#else
228 (void)metadata;
229 (void)features;
230 return false;
231#endif
232}
233
234bool VDBImageLoader::load_pixels(const ImageMetaData &, void *pixels, const size_t, const bool)
235{
236#ifdef WITH_OPENVDB
237# ifdef WITH_NANOVDB
238 if (nanogrid) {
239 memcpy(pixels, nanogrid.data(), nanogrid.size());
240 }
241 else
242# endif
243 {
244 ToDenseOp op;
245 op.pixels = pixels;
246 op.bbox = bbox;
247 openvdb::grid_type_operation(grid, op);
248 }
249 return true;
250#else
251 (void)pixels;
252 return false;
253#endif
254}
255
257{
258 return grid_name;
259}
260
261bool VDBImageLoader::equals(const ImageLoader &other) const
262{
263#ifdef WITH_OPENVDB
264 const VDBImageLoader &other_loader = (const VDBImageLoader &)other;
265 return grid == other_loader.grid;
266#else
267 (void)other;
268 return true;
269#endif
270}
271
273{
274#ifdef WITH_OPENVDB
275 /* Free OpenVDB grid memory as soon as we can. */
276 grid.reset();
277#endif
278#ifdef WITH_NANOVDB
279 nanogrid.reset();
280#endif
281}
282
284{
285 return true;
286}
287
288#ifdef WITH_OPENVDB
289openvdb::GridBase::ConstPtr VDBImageLoader::get_grid()
290{
291 return grid;
292}
293#endif
294
Group Output data from inside of a node group A color picker Mix two input colors RGB to Convert a color s luminance to a grayscale value Generate a normal vector and a dot product Brightness Control the brightness and contrast of the input color Vector Map input vector components with curves Camera Retrieve information about the camera and how it relates to the current shading point s position Clamp a value between a minimum and a maximum Vector Perform vector math operation Invert Invert a producing a negative Combine Generate a color from its and blue channels(Deprecated)") DefNode(ShaderNode
ATTR_WARN_UNUSED_RESULT const BMVert const BMEdge * e
SIMD_FORCE_INLINE btVector3 operator()(const btVector3 &x) const
Return the transform of the vector.
Definition btTransform.h:90
ImageDataType type
VDBImageLoader(const string &grid_name)
virtual bool equals(const ImageLoader &other) const override
string grid_name
Definition image_vdb.h:48
virtual bool load_metadata(const ImageDeviceFeatures &features, ImageMetaData &metadata) override
virtual void cleanup() override
virtual bool is_vdb_loader() const override
virtual string name() const override
virtual bool load_pixels(const ImageMetaData &metadata, void *pixels, const size_t pixels_size, const bool associate_alpha) override
#define CCL_NAMESPACE_END
draw_view in_light_buf[] float
uint col
#define VLOG_WARNING
Definition log.h:70
#define min(a, b)
Definition sort.c:32
ccl_device_inline Transform transform_identity()
Definition transform.h:296
ccl_device_inline Transform transform_translate(float3 t)
Definition transform.h:244
ccl_device_inline Transform transform_inverse(const Transform tfm)
Definition transform.h:423
ccl_device_inline Transform transform_scale(float3 s)
Definition transform.h:254
@ IMAGE_DATA_TYPE_FLOAT
@ IMAGE_DATA_TYPE_NANOVDB_FP16
@ IMAGE_DATA_TYPE_FLOAT4
@ IMAGE_DATA_TYPE_NANOVDB_FLOAT
@ IMAGE_DATA_TYPE_NANOVDB_FLOAT3
@ IMAGE_DATA_TYPE_NANOVDB_FPN