14# include <openvdb/openvdb.h>
16namespace blender::bke::volume_grid::file_cache {
26 openvdb::GridBase::Ptr meta_data_grid;
40 std::string error_message;
44 openvdb::MetaMap meta_data;
48 Vector<GridCache> grids;
50 GridCache *grid_cache_by_name(
const StringRef name)
52 for (GridCache &grid_cache : this->grids) {
53 if (grid_cache.meta_data_grid->getName() == name) {
72static GlobalCache &get_global_cache()
74 static GlobalCache global_cache;
82static FileCache create_file_cache(
const StringRef file_path)
86 openvdb::io::File file(file_path);
87 openvdb::GridPtrVec vdb_grids;
91 const bool delay_load =
false;
92 file.setCopyMaxBytes(0);
93 file.open(delay_load);
94 vdb_grids = *(file.readAllGridMetadata());
95 file_cache.meta_data = *file.getMetadata();
97 catch (
const openvdb::IoError &
e) {
98 file_cache.error_message =
e.what();
101 file_cache.error_message =
"Unknown error reading VDB file";
103 if (!file_cache.error_message.empty()) {
107 for (openvdb::GridBase::Ptr &vdb_grid : vdb_grids) {
111 GridCache grid_cache;
112 grid_cache.meta_data_grid = vdb_grid;
113 file_cache.grids.append(std::move(grid_cache));
119static FileCache &get_file_cache(
const StringRef file_path)
121 GlobalCache &global_cache = get_global_cache();
124 return global_cache.file_map.lookup_or_add_cb_as(file_path,
125 [&]() {
return create_file_cache(file_path); });
131class GridReadKey :
public GenericKey {
133 std::string file_path;
134 std::string grid_name;
139 return get_default_hash(this->file_path, this->grid_name, this->simplify_level);
144 bool equal_to(
const GenericKey &other)
const override
146 if (
const auto *other_typed =
dynamic_cast<const GridReadKey *
>(&other)) {
147 return *
this == *other_typed;
152 std::unique_ptr<GenericKey> to_storable()
const override
154 return std::make_unique<GridReadKey>(*
this);
158class GridReadValue :
public memory_cache::CachedValue {
160 mutable std::atomic<int64_t> bytes_ = 0;
163 ImplicitSharingPtr<> tree_sharing_info;
164 openvdb::GridBase::Ptr grid;
170 this->bytes_ = grid->baseTree().memUsage();
180static openvdb::GridBase::Ptr load_single_grid_from_disk(
const StringRef file_path,
181 const StringRef grid_name)
185 const bool delay_load =
false;
187 openvdb::io::File file(file_path);
188 file.setCopyMaxBytes(0);
189 file.open(delay_load);
190 return file.readGrid(grid_name);
197static LazyLoadedGrid load_single_grid_from_disk_cached(
const StringRef file_path,
198 const StringRef grid_name,
199 const int simplify_level)
202 key.file_path = file_path;
203 key.grid_name = grid_name;
204 key.simplify_level = simplify_level;
206 std::shared_ptr<const GridReadValue> value = memory_cache::get<GridReadValue>(key, [&key]() {
207 openvdb::GridBase::Ptr grid;
208 if (key.simplify_level == 0) {
209 grid = load_single_grid_from_disk(key.file_path, key.grid_name);
213 const GVolumeGrid main_grid = get_grid_from_file(key.file_path, key.grid_name, 0);
215 const float resolution_factor = 1.0f / (1 << key.simplify_level);
216 VolumeTreeAccessToken tree_token;
217 grid = BKE_volume_grid_create_with_changed_resolution(
218 grid_type, main_grid->grid(tree_token), resolution_factor);
220 auto value = std::make_unique<GridReadValue>();
221 value->grid = std::move(grid);
222 value->tree_sharing_info = OpenvdbTreeSharingInfo::make(value->grid->baseTreePtr());
230 openvdb::GridBase::Ptr grid = value->grid->copyGrid();
231 grid->setTransform(grid->transform().copy());
232 return {grid, value->tree_sharing_info};
239static GVolumeGrid get_cached_grid(
const StringRef file_path,
240 GridCache &grid_cache,
241 const int simplify_level)
243 if (GVolumeGrid *grid = grid_cache.grid_by_simplify_level.lookup_ptr(simplify_level)) {
247 auto load_grid_fn = [file_path = std::string(file_path),
248 grid_name = std::string(grid_cache.meta_data_grid->getName()),
249 simplify_level]() -> LazyLoadedGrid {
250 return load_single_grid_from_disk_cached(file_path, grid_name, simplify_level);
254 openvdb::GridBase::Ptr meta_data_and_transform_grid;
255 if (simplify_level == 0) {
258 meta_data_and_transform_grid = grid_cache.meta_data_grid->copyGrid();
260 VolumeGridData *grid_data = MEM_new<VolumeGridData>(
261 __func__, load_grid_fn, meta_data_and_transform_grid);
262 GVolumeGrid grid{grid_data};
263 grid_cache.grid_by_simplify_level.add(simplify_level, grid);
267GVolumeGrid get_grid_from_file(
const StringRef file_path,
268 const StringRef grid_name,
269 const int simplify_level)
271 GlobalCache &global_cache = get_global_cache();
272 std::lock_guard
lock{global_cache.mutex};
273 FileCache &file_cache = get_file_cache(file_path);
274 if (GridCache *grid_cache = file_cache.grid_cache_by_name(grid_name)) {
275 return get_cached_grid(file_path, *grid_cache, simplify_level);
280GridsFromFile get_all_grids_from_file(
const StringRef file_path,
const int simplify_level)
283 GlobalCache &global_cache = get_global_cache();
284 std::lock_guard
lock{global_cache.mutex};
285 FileCache &file_cache = get_file_cache(file_path);
287 if (!file_cache.error_message.empty()) {
288 result.error_message = file_cache.error_message;
291 result.file_meta_data = std::make_shared<openvdb::MetaMap>(file_cache.meta_data);
292 for (GridCache &grid_cache : file_cache.grids) {
293 result.grids.append(get_cached_grid(file_path, grid_cache, simplify_level));
300 GlobalCache &global_cache = get_global_cache();
301 std::lock_guard
lock{global_cache.mutex};
302 for (FileCache &file_cache : global_cache.file_map.values()) {
303 for (GridCache &grid_cache : file_cache.grids) {
304 grid_cache.grid_by_simplify_level.remove_if(
305 [&](
const auto &item) {
return item.value->is_mutable(); });
#define BLI_STRUCT_EQUALITY_OPERATORS_3(Type, m1, m2, m3)
in reality light always falls off quadratically Particle Retrieve the data of the particle that spawned the object for example to give variation to multiple instances of an object Point Retrieve information about points in a point cloud Retrieve the edges of an object as it appears to Cycles topology will always appear triangulated Convert a blackbody temperature to an RGB value Normal Map
ATTR_WARN_UNUSED_RESULT const BMVert const BMEdge * e
void count_memory(const VolumeGridData &grid, MemoryCounter &memory)
uint64_t get_default_hash(const T &v)
unsigned __int64 uint64_t