12# include <openvdb/Grid.h>
19VolumeGridData::VolumeGridData()
21 tree_access_token_ = std::make_shared<AccessToken>(*
this);
25 template<
typename Gr
idT> openvdb::GridBase::Ptr
operator()()
const
27 return GridT::create();
31static openvdb::GridBase::Ptr create_grid_for_type(
const VolumeGridType grid_type)
33 return BKE_volume_grid_type_operation(grid_type, CreateGridOp{});
37 : VolumeGridData(create_grid_for_type(grid_type))
41VolumeGridData::VolumeGridData(std::shared_ptr<openvdb::GridBase> grid)
42 : grid_(std::move(grid)), tree_loaded_(
true), transform_loaded_(
true), meta_data_loaded_(
true)
48 tree_sharing_info_ = OpenvdbTreeSharingInfo::make(grid_->baseTreePtr());
49 tree_access_token_ = std::make_shared<AccessToken>(*
this);
52VolumeGridData::VolumeGridData(std::function<LazyLoadedGrid()> lazy_load_grid,
53 std::shared_ptr<openvdb::GridBase> meta_data_and_transform_grid)
54 : grid_(std::move(meta_data_and_transform_grid)), lazy_load_grid_(std::move(lazy_load_grid))
57 transform_loaded_ =
true;
58 meta_data_loaded_ =
true;
60 tree_access_token_ = std::make_shared<AccessToken>(*
this);
63VolumeGridData::~VolumeGridData() =
default;
65void VolumeGridData::delete_self()
70const openvdb::GridBase &VolumeGridData::grid(VolumeTreeAccessToken &r_token)
const
72 return *this->grid_ptr(r_token);
75openvdb::GridBase &VolumeGridData::grid_for_write(VolumeTreeAccessToken &r_token)
77 return *this->grid_ptr_for_write(r_token);
80std::shared_ptr<const openvdb::GridBase> VolumeGridData::grid_ptr(
81 VolumeTreeAccessToken &r_token)
const
83 std::lock_guard
lock{mutex_};
84 this->ensure_grid_loaded();
85 r_token.token_ = tree_access_token_;
89std::shared_ptr<openvdb::GridBase> VolumeGridData::grid_ptr_for_write(
90 VolumeTreeAccessToken &r_token)
93 std::lock_guard
lock{mutex_};
94 this->ensure_grid_loaded();
95 r_token.token_ = tree_access_token_;
96 if (tree_sharing_info_->is_mutable()) {
97 tree_sharing_info_->tag_ensured_mutable();
100 auto tree_copy = grid_->baseTree().copy();
101 grid_->setTree(tree_copy);
102 tree_sharing_info_ = OpenvdbTreeSharingInfo::make(std::move(tree_copy));
105 lazy_load_grid_ = {};
109const openvdb::math::Transform &VolumeGridData::transform()
const
111 std::lock_guard
lock{mutex_};
112 if (!transform_loaded_) {
113 this->ensure_grid_loaded();
115 return grid_->transform();
118openvdb::math::Transform &VolumeGridData::transform_for_write()
121 std::lock_guard
lock{mutex_};
122 if (!transform_loaded_) {
123 this->ensure_grid_loaded();
125 return grid_->transform();
128std::string VolumeGridData::name()
const
130 std::lock_guard
lock{mutex_};
131 if (!meta_data_loaded_) {
132 this->ensure_grid_loaded();
134 return grid_->getName();
137void VolumeGridData::set_name(
const StringRef name)
140 std::lock_guard
lock{mutex_};
141 if (!meta_data_loaded_) {
142 this->ensure_grid_loaded();
144 grid_->setName(name);
149 std::lock_guard
lock{mutex_};
150 if (!meta_data_loaded_) {
151 this->ensure_grid_loaded();
156std::optional<VolumeGridType> VolumeGridData::grid_type_without_load()
const
158 std::lock_guard
lock{mutex_};
159 if (!meta_data_loaded_) {
165openvdb::GridClass VolumeGridData::grid_class()
const
167 std::lock_guard
lock{mutex_};
168 if (!meta_data_loaded_) {
169 this->ensure_grid_loaded();
171 return grid_->getGridClass();
174bool VolumeGridData::is_reloadable()
const
176 return bool(lazy_load_grid_);
179bool VolumeGridData::is_loaded()
const
181 std::lock_guard
lock{mutex_};
182 return tree_loaded_ && transform_loaded_ && meta_data_loaded_;
185void VolumeGridData::count_memory(MemoryCounter &memory)
const
187 std::lock_guard
lock{mutex_};
191 const openvdb::TreeBase &
tree = grid_->baseTree();
192 memory.add_shared(tree_sharing_info_.get(),
193 [&](MemoryCounter &shared_memory) { shared_memory.add(tree.memUsage()); });
196std::string VolumeGridData::error_message()
const
198 std::lock_guard
lock{mutex_};
199 return error_message_;
202void VolumeGridData::unload_tree_if_possible()
const
204 std::lock_guard
lock{mutex_};
211 if (!this->is_reloadable()) {
214 if (tree_access_token_.use_count() != 1) {
219 tree_loaded_ =
false;
220 tree_sharing_info_.reset();
223GVolumeGrid VolumeGridData::copy()
const
225 std::lock_guard
lock{mutex_};
226 this->ensure_grid_loaded();
228 VolumeGridData *new_copy =
new (
MEM_mallocN(
sizeof(VolumeGridData), __func__)) VolumeGridData();
230 new_copy->grid_ = grid_->copyGrid();
231 new_copy->tree_sharing_info_ = tree_sharing_info_;
232 new_copy->tree_loaded_ = tree_loaded_;
233 new_copy->transform_loaded_ = transform_loaded_;
234 new_copy->meta_data_loaded_ = meta_data_loaded_;
235 return GVolumeGrid(new_copy);
238void VolumeGridData::ensure_grid_loaded()
const
243 if (tree_loaded_ && transform_loaded_ && meta_data_loaded_) {
247 LazyLoadedGrid loaded_grid;
249 threading::isolate_task([&]() {
250 error_message_.clear();
252 loaded_grid = lazy_load_grid_();
254 catch (
const openvdb::IoError &
e) {
255 error_message_ =
e.what();
258 error_message_ =
"Unknown error reading VDB file";
261 if (!loaded_grid.grid) {
264 const openvdb::Name &grid_type = grid_->type();
265 if (openvdb::GridBase::isRegistered(grid_type)) {
267 loaded_grid.grid = openvdb::GridBase::createGrid(grid_type);
271 if (!loaded_grid.grid) {
273 loaded_grid.grid = openvdb::FloatGrid::create();
278 if (!loaded_grid.tree_sharing_info) {
280 loaded_grid.tree_sharing_info = OpenvdbTreeSharingInfo::make(loaded_grid.grid->baseTreePtr());
287 grid_->setTree(loaded_grid.grid->baseTreePtr());
288 if (!transform_loaded_) {
289 grid_->setTransform(loaded_grid.grid->transformPtr());
293 grid_ = std::move(loaded_grid.grid);
298 tree_sharing_info_ = std::move(loaded_grid.tree_sharing_info);
301 transform_loaded_ =
true;
302 meta_data_loaded_ =
true;
305GVolumeGrid::GVolumeGrid(std::shared_ptr<openvdb::GridBase> grid)
307 data_ = ImplicitSharingPtr(MEM_new<VolumeGridData>(__func__, std::move(grid)));
311 : GVolumeGrid(create_grid_for_type(grid_type))
315VolumeGridData &GVolumeGrid::get_for_write()
318 if (data_->is_mutable()) {
319 data_->tag_ensured_mutable();
322 *
this = data_->copy();
324 return const_cast<VolumeGridData &
>(*data_);
329 if (grid.isType<openvdb::FloatGrid>()) {
332 if (grid.isType<openvdb::Vec3fGrid>()) {
335 if (grid.isType<openvdb::BoolGrid>()) {
338 if (grid.isType<openvdb::DoubleGrid>()) {
341 if (grid.isType<openvdb::Int32Grid>()) {
344 if (grid.isType<openvdb::Int64Grid>()) {
347 if (grid.isType<openvdb::Vec3IGrid>()) {
350 if (grid.isType<openvdb::Vec3dGrid>()) {
353 if (grid.isType<openvdb::MaskGrid>()) {
356 if (grid.isType<openvdb::points::PointDataGrid>()) {
362ImplicitSharingPtr<> OpenvdbTreeSharingInfo::make(std::shared_ptr<openvdb::tree::TreeBase>
tree)
364 return ImplicitSharingPtr<>{MEM_new<OpenvdbTreeSharingInfo>(__func__, std::move(
tree))};
367OpenvdbTreeSharingInfo::OpenvdbTreeSharingInfo(std::shared_ptr<openvdb::tree::TreeBase>
tree)
368 : tree_(std::move(
tree))
372void OpenvdbTreeSharingInfo::delete_self_with_data()
377void OpenvdbTreeSharingInfo::delete_data_only()
382VolumeTreeAccessToken::~VolumeTreeAccessToken()
384 const VolumeGridData *grid = token_ ? &token_->grid :
nullptr;
389 grid->unload_tree_if_possible();
395std::string
get_name(
const VolumeGridData &volume_grid)
398 return volume_grid.name();
408 return volume_grid.grid_type();
439 const openvdb::math::Transform &transform = grid.transform();
443 openvdb::math::Mat4f matrix = transform.baseMap()->getAffineMap()->getMat4();
447 for (
int row = 0; row < 4; row++) {
448 result[
col][row] = matrix(
col, row);
454 return float4x4::identity();
461 openvdb::math::Mat4f matrix_openvdb;
463 for (
int row = 0; row < 4; row++) {
464 matrix_openvdb(
col, row) = matrix[
col][row];
468 grid.transform_for_write() = openvdb::math::Transform(
469 std::make_shared<openvdb::math::AffineMap>(matrix_openvdb));
478 VolumeTreeAccessToken tree_token;
479 grid.grid_for_write(tree_token).clear();
488 return grid.is_loaded();
498 grid.count_memory(memory);
504void load(
const VolumeGridData &grid)
507 VolumeTreeAccessToken tree_token;
509 grid.grid(tree_token);
518 return grid.error_message();
@ VOLUME_GRID_VECTOR_FLOAT
@ VOLUME_GRID_VECTOR_DOUBLE
ATTR_WARN_UNUSED_RESULT const BMVert const BMEdge * e
void *(* MEM_mallocN)(size_t len, const char *str)
float4x4 get_transform_matrix(const VolumeGridData &grid)
std::string get_name(const VolumeGridData &grid)
void count_memory(const VolumeGridData &grid, MemoryCounter &memory)
int get_channels_num(VolumeGridType type)
std::string error_message_from_load(const VolumeGridData &grid)
void load(const VolumeGridData &grid)
void clear_tree(VolumeGridData &grid)
VolumeGridType get_type(const VolumeGridData &grid)
void set_transform_matrix(VolumeGridData &grid, const float4x4 &matrix)
bool is_loaded(const VolumeGridData &grid)