Blender V4.3
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
12
13#ifdef WITH_OPENVDB
14
15# include <functional>
16# include <mutex>
17# include <optional>
18
19# include "BKE_volume_enums.hh"
21
23# include "BLI_string_ref.hh"
24
25# include "openvdb_fwd.hh"
26
28
33struct LazyLoadedGrid {
39 std::shared_ptr<openvdb::GridBase> grid;
40 ImplicitSharingPtr<> tree_sharing_info;
41};
42
69class VolumeGridData : public ImplicitSharingMixin {
70 private:
74 struct AccessToken {
75 const VolumeGridData &grid;
76
77 AccessToken(const VolumeGridData &grid) : grid(grid) {}
78 };
79
83 mutable std::mutex mutex_;
99 mutable std::shared_ptr<openvdb::GridBase> grid_;
103 mutable ImplicitSharingPtr<> tree_sharing_info_;
104
106 mutable bool tree_loaded_ = false;
108 mutable bool transform_loaded_ = false;
110 mutable bool meta_data_loaded_ = false;
111
115 std::function<LazyLoadedGrid()> lazy_load_grid_;
119 mutable std::string error_message_;
126 std::shared_ptr<AccessToken> tree_access_token_;
127
128 friend class VolumeTreeAccessToken;
129
131 VolumeGridData();
132
133 public:
138 explicit VolumeGridData(VolumeGridType grid_type);
139
144 explicit VolumeGridData(std::shared_ptr<openvdb::GridBase> grid);
145
155 explicit VolumeGridData(std::function<LazyLoadedGrid()> lazy_load_grid,
156 std::shared_ptr<openvdb::GridBase> meta_data_and_transform_grid = {});
157
158 ~VolumeGridData();
159
167 GVolumeGrid copy() const;
168
173 const openvdb::GridBase &grid(VolumeTreeAccessToken &r_token) const;
178 openvdb::GridBase &grid_for_write(VolumeTreeAccessToken &r_token);
179
185 std::shared_ptr<const openvdb::GridBase> grid_ptr(VolumeTreeAccessToken &r_token) const;
186 std::shared_ptr<openvdb::GridBase> grid_ptr_for_write(VolumeTreeAccessToken &r_token);
187
191 std::string name() const;
195 void set_name(StringRef name);
196
201 const openvdb::math::Transform &transform() const;
206 openvdb::math::Transform &transform_for_write();
207
211 VolumeGridType grid_type() const;
212
217 std::optional<VolumeGridType> grid_type_without_load() const;
218
222 openvdb::GridClass grid_class() const;
223
227 bool is_loaded() const;
228
229 void count_memory(MemoryCounter &memory) const;
230
234 std::string error_message() const;
235
239 bool is_reloadable() const;
240
241 private:
245 void unload_tree_if_possible() const;
246
247 void ensure_grid_loaded() const;
248 void delete_self();
249};
250
256class OpenvdbTreeSharingInfo : public ImplicitSharingInfo {
257 private:
258 std::shared_ptr<openvdb::tree::TreeBase> tree_;
259
260 public:
261 OpenvdbTreeSharingInfo(std::shared_ptr<openvdb::tree::TreeBase> tree);
262
263 static ImplicitSharingPtr<> make(std::shared_ptr<openvdb::tree::TreeBase> tree);
264
265 void delete_self_with_data() override;
266 void delete_data_only() override;
267};
268
269class VolumeTreeAccessToken {
270 private:
271 std::shared_ptr<VolumeGridData::AccessToken> token_;
272
273 friend VolumeGridData;
274
275 public:
281 VolumeTreeAccessToken() = default;
282 VolumeTreeAccessToken(const VolumeTreeAccessToken &) = default;
283 VolumeTreeAccessToken(VolumeTreeAccessToken &&) = default;
284 VolumeTreeAccessToken &operator=(const VolumeTreeAccessToken &) = default;
285 VolumeTreeAccessToken &operator=(VolumeTreeAccessToken &&) = default;
286 ~VolumeTreeAccessToken();
287
289 bool valid_for(const VolumeGridData &grid) const;
290
292 void reset();
293};
294
299class GVolumeGrid {
300 protected:
301 ImplicitSharingPtr<VolumeGridData> data_;
302
303 public:
307 GVolumeGrid() = default;
312 explicit GVolumeGrid(const VolumeGridData *data);
316 explicit GVolumeGrid(std::shared_ptr<openvdb::GridBase> grid);
321 explicit GVolumeGrid(VolumeGridType grid_type);
322
326 const VolumeGridData &get() const;
327
332 VolumeGridData &get_for_write();
333
337 const VolumeGridData *release();
338
340 const VolumeGridData *operator->() const;
341
343 operator bool() const;
344
346 template<typename T> VolumeGrid<T> typed() const;
347};
348
353template<typename T> class VolumeGrid : public GVolumeGrid {
354 public:
355 using base_type = T;
356
357 VolumeGrid() = default;
358 explicit VolumeGrid(const VolumeGridData *data);
359 explicit VolumeGrid(std::shared_ptr<OpenvdbGridType<T>> grid);
360
364 const OpenvdbGridType<T> &grid(VolumeTreeAccessToken &r_token) const;
365 OpenvdbGridType<T> &grid_for_write(VolumeTreeAccessToken &r_token);
366
367 private:
368 void assert_correct_type() const;
369};
370
374VolumeGridType get_type(const openvdb::GridBase &grid);
375
376/* -------------------------------------------------------------------- */
380inline GVolumeGrid::GVolumeGrid(const VolumeGridData *data) : data_(data) {}
381
382inline const VolumeGridData &GVolumeGrid::get() const
383{
384 BLI_assert(*this);
385 return *data_.get();
386}
387
388inline const VolumeGridData *GVolumeGrid::release()
389{
390 return data_.release();
391}
392
393inline GVolumeGrid::operator bool() const
394{
395 return bool(data_);
396}
397
398template<typename T> inline VolumeGrid<T> GVolumeGrid::typed() const
399{
400 if (data_) {
401 data_->add_user();
402 }
403 return VolumeGrid<T>(data_.get());
404}
405
406inline const VolumeGridData *GVolumeGrid::operator->() const
407{
408 BLI_assert(*this);
409 return data_.get();
410}
411
412template<typename T>
413inline VolumeGrid<T>::VolumeGrid(const VolumeGridData *data) : GVolumeGrid(data)
414{
415 this->assert_correct_type();
416}
417
418template<typename T>
419inline VolumeGrid<T>::VolumeGrid(std::shared_ptr<OpenvdbGridType<T>> grid)
420 : GVolumeGrid(std::move(grid))
421{
422 this->assert_correct_type();
423}
424
425template<typename T>
426inline const OpenvdbGridType<T> &VolumeGrid<T>::grid(VolumeTreeAccessToken &r_token) const
427{
428 return static_cast<const OpenvdbGridType<T> &>(data_->grid(r_token));
429}
430
431template<typename T>
432inline OpenvdbGridType<T> &VolumeGrid<T>::grid_for_write(VolumeTreeAccessToken &r_token)
433{
434 return static_cast<OpenvdbGridType<T> &>(this->get_for_write().grid_for_write(r_token));
435}
436
437template<typename T> inline void VolumeGrid<T>::assert_correct_type() const
438{
439# ifndef NDEBUG
440 if (data_) {
441 const VolumeGridType expected_type = VolumeGridTraits<T>::EnumType;
442 if (const std::optional<VolumeGridType> actual_type = data_->grid_type_without_load()) {
443 BLI_assert(expected_type == *actual_type);
444 }
445 }
446# endif
447}
448
449inline bool VolumeTreeAccessToken::valid_for(const VolumeGridData &grid) const
450{
451 return grid.tree_access_token_ == token_;
452}
453
454inline void VolumeTreeAccessToken::reset()
455{
456 token_.reset();
457}
458
461} // namespace blender::bke::volume_grid
462
463#endif /* WITH_OPENVDB */
VolumeGridType
#define BLI_assert(a)
Definition BLI_assert.h:50
SIMD_FORCE_INLINE btVector3 transform(const btVector3 &point) const
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:244
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)
static void copy(bNodeTree *dest_ntree, bNode *dest_node, const bNode *src_node)