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