Blender V5.0
BKE_volume_grid.hh
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2023 Blender Foundation
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
5#pragma once
6
10
12
13#ifdef WITH_OPENVDB
14
15# include <functional>
16# include <optional>
17
18# include "BKE_volume_enums.hh"
20
21# include "BLI_cache_mutex.hh"
23# include "BLI_mutex.hh"
24# include "BLI_string_ref.hh"
25
26# include "openvdb_fwd.hh"
27
29
34struct LazyLoadedGrid {
40 std::shared_ptr<openvdb::GridBase> grid;
41 ImplicitSharingPtr<> tree_sharing_info;
42};
43
70class VolumeGridData : public ImplicitSharingMixin {
71 private:
75 struct AccessToken {
76 const VolumeGridData &grid;
77
78 AccessToken(const VolumeGridData &grid) : grid(grid) {}
79 };
80
84 mutable Mutex mutex_;
100 mutable std::shared_ptr<openvdb::GridBase> grid_;
104 mutable ImplicitSharingPtr<> tree_sharing_info_;
105
107 mutable bool tree_loaded_ = false;
109 mutable bool transform_loaded_ = false;
111 mutable bool meta_data_loaded_ = false;
112
116 std::function<LazyLoadedGrid()> lazy_load_grid_;
120 mutable std::string error_message_;
121
122 mutable CacheMutex active_voxels_mutex_;
123 mutable int64_t active_voxels_ = 0;
124 mutable CacheMutex active_leaf_voxels_mutex_;
125 mutable int64_t active_leaf_voxels_ = 0;
126 mutable CacheMutex active_tiles_mutex_;
127 mutable int64_t active_tiles_ = 0;
128 mutable CacheMutex size_in_bytes_mutex_;
129 mutable int64_t size_in_bytes_ = 0;
130 mutable CacheMutex active_bounds_mutex_;
131 mutable openvdb::CoordBBox active_bounds_;
132
139 std::shared_ptr<AccessToken> tree_access_token_;
140
141 friend class VolumeTreeAccessToken;
142
144 VolumeGridData();
145
146 public:
151 explicit VolumeGridData(VolumeGridType grid_type);
152
157 explicit VolumeGridData(std::shared_ptr<openvdb::GridBase> grid);
158
168 explicit VolumeGridData(std::function<LazyLoadedGrid()> lazy_load_grid,
169 std::shared_ptr<openvdb::GridBase> meta_data_and_transform_grid = {});
170
171 ~VolumeGridData() override;
172
180 GVolumeGrid copy() const;
181
186 const openvdb::GridBase &grid(VolumeTreeAccessToken &r_token) const;
191 openvdb::GridBase &grid_for_write(VolumeTreeAccessToken &r_token);
192
198 std::shared_ptr<const openvdb::GridBase> grid_ptr(VolumeTreeAccessToken &r_token) const;
199 std::shared_ptr<openvdb::GridBase> grid_ptr_for_write(VolumeTreeAccessToken &r_token);
200
204 std::string name() const;
208 void set_name(StringRef name);
209
214 const openvdb::math::Transform &transform() const;
219 openvdb::math::Transform &transform_for_write();
220
224 VolumeGridType grid_type() const;
225
230 std::optional<VolumeGridType> grid_type_without_load() const;
231
235 openvdb::GridClass grid_class() const;
236
240 bool is_loaded() const;
241
242 void count_memory(MemoryCounter &memory) const;
243
247 std::string error_message() const;
248
252 bool is_reloadable() const;
253
254 void tag_tree_modified() const;
255
256 int64_t active_voxels() const;
257 int64_t active_leaf_voxels() const;
258 int64_t active_tiles() const;
259 int64_t size_in_bytes() const;
260 const openvdb::CoordBBox &active_bounds() const;
261
262 private:
266 void unload_tree_if_possible() const;
267
268 void ensure_grid_loaded() const;
269 void delete_self() override;
270};
271
277class OpenvdbTreeSharingInfo : public ImplicitSharingInfo {
278 private:
279 std::shared_ptr<openvdb::tree::TreeBase> tree_;
280
281 public:
282 OpenvdbTreeSharingInfo(std::shared_ptr<openvdb::tree::TreeBase> tree);
283
284 static ImplicitSharingPtr<> make(std::shared_ptr<openvdb::tree::TreeBase> tree);
285
286 void delete_self_with_data() override;
287 void delete_data_only() override;
288};
289
290class VolumeTreeAccessToken {
291 private:
292 std::shared_ptr<VolumeGridData::AccessToken> token_;
293
294 friend VolumeGridData;
295
296 public:
302 VolumeTreeAccessToken() = default;
303 VolumeTreeAccessToken(const VolumeTreeAccessToken &) = default;
304 VolumeTreeAccessToken(VolumeTreeAccessToken &&) = default;
305 VolumeTreeAccessToken &operator=(const VolumeTreeAccessToken &) = default;
306 VolumeTreeAccessToken &operator=(VolumeTreeAccessToken &&) = default;
307 ~VolumeTreeAccessToken();
308
310 bool valid_for(const VolumeGridData &grid) const;
311
313 void reset();
314};
315
320class GVolumeGrid {
321 protected:
322 ImplicitSharingPtr<VolumeGridData> data_;
323
324 public:
328 GVolumeGrid() = default;
333 explicit GVolumeGrid(const VolumeGridData *data);
337 explicit GVolumeGrid(std::shared_ptr<openvdb::GridBase> grid);
342 explicit GVolumeGrid(VolumeGridType grid_type);
343
347 const VolumeGridData &get() const;
348
353 VolumeGridData &get_for_write();
354
358 const VolumeGridData *release();
359
361 const VolumeGridData *operator->() const;
362
364 operator bool() const;
365
367 template<typename T> VolumeGrid<T> typed() const;
368};
369
374template<typename T> class VolumeGrid : public GVolumeGrid {
375 public:
376 using base_type = T;
377
378 VolumeGrid() = default;
379 explicit VolumeGrid(const VolumeGridData *data);
380 explicit VolumeGrid(std::shared_ptr<OpenvdbGridType<T>> grid);
381
385 const OpenvdbGridType<T> &grid(VolumeTreeAccessToken &r_token) const;
386 OpenvdbGridType<T> &grid_for_write(VolumeTreeAccessToken &r_token);
387
388 private:
389 void assert_correct_type() const;
390};
391
395VolumeGridType get_type(const openvdb::tree::TreeBase &tree);
399VolumeGridType get_type(const openvdb::GridBase &grid);
400
401/* -------------------------------------------------------------------- */
404
405inline GVolumeGrid::GVolumeGrid(const VolumeGridData *data) : data_(data) {}
406
407inline const VolumeGridData &GVolumeGrid::get() const
408{
409 BLI_assert(*this);
410 return *data_;
411}
412
413inline const VolumeGridData *GVolumeGrid::release()
414{
415 return data_.release();
416}
417
418inline GVolumeGrid::operator bool() const
419{
420 return bool(data_);
421}
422
423template<typename T> inline VolumeGrid<T> GVolumeGrid::typed() const
424{
425 if (data_) {
426 data_->add_user();
427 }
428 return VolumeGrid<T>(data_.get());
429}
430
431inline const VolumeGridData *GVolumeGrid::operator->() const
432{
433 BLI_assert(*this);
434 return data_.get();
435}
436
437template<typename T>
438inline VolumeGrid<T>::VolumeGrid(const VolumeGridData *data) : GVolumeGrid(data)
439{
440 this->assert_correct_type();
441}
442
443template<typename T>
444inline VolumeGrid<T>::VolumeGrid(std::shared_ptr<OpenvdbGridType<T>> grid)
445 : GVolumeGrid(std::move(grid))
446{
447 this->assert_correct_type();
448}
449
450template<typename T>
451inline const OpenvdbGridType<T> &VolumeGrid<T>::grid(VolumeTreeAccessToken &r_token) const
452{
453 return static_cast<const OpenvdbGridType<T> &>(data_->grid(r_token));
454}
455
456template<typename T>
457inline OpenvdbGridType<T> &VolumeGrid<T>::grid_for_write(VolumeTreeAccessToken &r_token)
458{
459 return static_cast<OpenvdbGridType<T> &>(this->get_for_write().grid_for_write(r_token));
460}
461
462template<typename T> inline void VolumeGrid<T>::assert_correct_type() const
463{
464# ifndef NDEBUG
465 if (data_) {
466 const VolumeGridType expected_type = VolumeGridTraits<T>::EnumType;
467 if (const std::optional<VolumeGridType> actual_type = data_->grid_type_without_load()) {
468 BLI_assert(expected_type == *actual_type);
469 }
470 }
471# endif
472}
473
474inline bool VolumeTreeAccessToken::valid_for(const VolumeGridData &grid) const
475{
476 return grid.tree_access_token_ == token_;
477}
478
479inline void VolumeTreeAccessToken::reset()
480{
481 token_.reset();
482}
483
485
486} // namespace blender::bke::volume_grid
487
488#endif /* WITH_OPENVDB */
VolumeGridType
#define BLI_assert(a)
Definition BLI_assert.h:46
BMesh const char void * data
SIMD_FORCE_INLINE btVector3 transform(const btVector3 &point) const
long long int int64_t
btGeneric6DofConstraint & operator=(btGeneric6DofConstraint &other)
void reset()
clear internal cached data and reset random seed
KDTree_3d * tree
#define T
static int make(const char *input_file_name, const char *output_file_name)
Definition msgfmt.cc:239
void count_memory(const VolumeGridData &grid, MemoryCounter &memory)
VolumeGridType get_type(const VolumeGridData &grid)
bool is_loaded(const VolumeGridData &grid)
std::shared_ptr< const T > get(const GenericKey &key, FunctionRef< std::unique_ptr< T >()> compute_fn)
std::mutex Mutex
Definition BLI_mutex.hh:47
static void copy(bNodeTree *dest_ntree, bNode *dest_node, const bNode *src_node)
const char * name