[Bf-blender-cvs] [e893f5c61ac] new-object-types: Volumes: work on completing the grid access API
Brecht Van Lommel
noreply at git.blender.org
Fri Jan 31 11:02:43 CET 2020
Commit: e893f5c61ac0f67e7cf1f6729966b59bec539986
Author: Brecht Van Lommel
Date: Wed Jan 29 20:48:33 2020 +0100
Branches: new-object-types
https://developer.blender.org/rBe893f5c61ac0f67e7cf1f6729966b59bec539986
Volumes: work on completing the grid access API
===================================================================
M source/blender/blenkernel/BKE_volume.h
M source/blender/blenkernel/intern/volume.cc
M source/blender/draw/intern/draw_cache_impl_volume.c
M source/blender/makesrna/intern/rna_volume.c
M source/creator/creator.c
===================================================================
diff --git a/source/blender/blenkernel/BKE_volume.h b/source/blender/blenkernel/BKE_volume.h
index 7b85fdb3d0e..75b8db09c21 100644
--- a/source/blender/blenkernel/BKE_volume.h
+++ b/source/blender/blenkernel/BKE_volume.h
@@ -38,6 +38,12 @@ struct Object;
struct Scene;
struct Volume;
+/* Module */
+
+void BKE_volumes_init(void);
+
+/* Datablock Management */
+
void BKE_volume_init(struct Volume *volume);
void BKE_volume_init_grids(struct Volume *volume);
void *BKE_volume_add(struct Main *bmain, const char *name);
@@ -49,9 +55,6 @@ struct Volume *BKE_volume_copy(struct Main *bmain, const struct Volume *volume);
void BKE_volume_make_local(struct Main *bmain, struct Volume *volume, const bool lib_local);
void BKE_volume_free(struct Volume *volume);
-void BKE_volume_load(struct Volume *volume, struct Main *bmain);
-void BKE_volume_unload(struct Volume *volume);
-
struct BoundBox *BKE_volume_boundbox_get(struct Object *ob);
/* Depsgraph */
@@ -77,27 +80,64 @@ extern void (*BKE_volume_batch_cache_free_cb)(struct Volume *volume);
/* Grids
*
- * When accessing a grid, it must be specified if the grid will be used for
- * reading only metadata, or reading metadata and voxels.
- *
- * This makes it possible to load just the required data on-demand, and share
- * grids between volumes for copy-on-write. */
+ * For volumes referencing a file, the list of grids and metadata must be
+ * loaded before it can be accessed. This happens on-demand, only when needed
+ * by the user interface, dependency graph or render engine. */
typedef struct VolumeGrid VolumeGrid;
+bool BKE_volume_load(struct Volume *volume, struct Main *bmain);
+void BKE_volume_unload(struct Volume *volume);
+bool BKE_volume_is_loaded(const struct Volume *volume);
+
int BKE_volume_num_grids(struct Volume *volume);
const char *BKE_volume_grids_error_msg(const struct Volume *volume);
+VolumeGrid *BKE_volume_grid_get(struct Volume *volume, int grid_index);
+VolumeGrid *BKE_volume_grid_find(struct Volume *volume, const char *name);
-/* Grid Metadata */
-
-const VolumeGrid *BKE_volume_grid_for_metadata(struct Volume *volume, int grid_index);
+/* Grid
+ *
+ * By default only grid metadata is loaded, for access to the tree and voxels
+ * the BKE_volume_grid_load must be called first. */
+
+typedef enum VolumeGridType {
+ VOLUME_GRID_UNKNOWN = 0,
+ VOLUME_GRID_BOOLEAN,
+ VOLUME_GRID_FLOAT,
+ VOLUME_GRID_DOUBLE,
+ VOLUME_GRID_INT,
+ VOLUME_GRID_INT64,
+ VOLUME_GRID_MASK,
+ VOLUME_GRID_STRING,
+ VOLUME_GRID_VECTOR_FLOAT,
+ VOLUME_GRID_VECTOR_DOUBLE,
+ VOLUME_GRID_VECTOR_INT,
+} VolumeGridType;
+
+bool BKE_volume_grid_load(struct Volume *volume, struct VolumeGrid *grid);
+void BKE_volume_grid_unload(struct VolumeGrid *volume);
+bool BKE_volume_grid_is_loaded(const struct VolumeGrid *grid);
+
+/* Metadata */
const char *BKE_volume_grid_name(const struct VolumeGrid *grid);
+VolumeGridType BKE_volume_grid_type(const struct VolumeGrid *grid);
+int BKE_volume_grid_channels(const struct VolumeGrid *grid);
+void BKE_volume_grid_transform_matrix(const struct VolumeGrid *grid, float mat[4][4]);
-/* Grid Tree and Voxels */
-
-const VolumeGrid *BKE_volume_grid_for_tree(struct Volume *volume, int grid_index);
+/* Tree and Voxels */
bool BKE_volume_grid_bounds(const struct VolumeGrid *grid, float min[3], float max[3]);
-float *BKE_volume_grid_to_dense_voxels(const struct VolumeGrid *volume_grid, size_t size[3]);
+
+bool BKE_volume_grid_dense_bounds(const struct VolumeGrid *volume_grid,
+ size_t min[3],
+ size_t max[3]);
+void BKE_volume_grid_dense_transform_matrix(const struct VolumeGrid *volume_grid,
+ const size_t min[3],
+ const size_t max[3],
+ float mat[4][4]);
+void BKE_volume_grid_dense_voxels(const struct VolumeGrid *volume_grid,
+ const size_t min[3],
+ const size_t max[3],
+ float *voxels);
#ifdef __cplusplus
}
diff --git a/source/blender/blenkernel/intern/volume.cc b/source/blender/blenkernel/intern/volume.cc
index 5ecb5ae6904..7a867099560 100644
--- a/source/blender/blenkernel/intern/volume.cc
+++ b/source/blender/blenkernel/intern/volume.cc
@@ -48,18 +48,19 @@
# include <openvdb/tools/Dense.h>
struct VolumeGrid {
- VolumeGrid(const openvdb::GridBase::Ptr &vdb, const bool has_tree) : vdb(vdb), has_tree(has_tree)
+ VolumeGrid(const openvdb::GridBase::Ptr &vdb, const bool is_loaded)
+ : vdb(vdb), is_loaded(is_loaded)
{
}
- VolumeGrid(const VolumeGrid &other) : vdb(other.vdb), has_tree(other.has_tree)
+ VolumeGrid(const VolumeGrid &other) : vdb(other.vdb), is_loaded(other.is_loaded)
{
}
/* OpenVDB grid. */
openvdb::GridBase::Ptr vdb;
/* Grid may have only metadata and no tree. */
- bool has_tree;
+ bool is_loaded;
/* Mutex for on-demand reading of tree. */
std::mutex mutex;
};
@@ -70,13 +71,29 @@ struct VolumeGridVector : public std::vector<VolumeGrid> {
filepath[0] = '\0';
}
+ VolumeGridVector(const VolumeGridVector &other) : error_msg(other.error_msg)
+ {
+ memcpy(filepath, other.filepath, sizeof(filepath));
+ }
+
/* Absolute file path that grids have been loaded from. */
char filepath[FILE_MAX];
/* File loading error message. */
std::string error_msg;
+ /* Mutex for file loading of grids list. */
+ std::mutex mutex;
};
#endif
+/* Module */
+
+void BKE_volumes_init()
+{
+#ifdef WITH_OPENVDB
+ openvdb::initialize();
+#endif
+}
+
/* Volume datablock */
void BKE_volume_init(Volume *volume)
@@ -149,24 +166,36 @@ void BKE_volume_free(Volume *volume)
#endif
}
-void BKE_volume_load(Volume *volume, Main *bmain)
+bool BKE_volume_is_loaded(const Volume *volume)
+{
+#ifdef WITH_OPENVDB
+ /* Test if there is a file to load, or if already loaded. */
+ return (volume->filepath[0] == '\0' || volume->grids->filepath[0] != '\0');
+#else
+ UNUSED_VARS(volume);
+ return true;
+#endif
+}
+
+bool BKE_volume_load(Volume *volume, Main *bmain)
{
#ifdef WITH_OPENVDB
VolumeGridVector &grids = *volume->grids;
- /* Test if there is a file to load, or if already loaded. */
- if (volume->filepath[0] == '\0' || grids.filepath[0] != '\0') {
- return;
+ if (BKE_volume_is_loaded(volume)) {
+ return grids.error_msg.empty();
+ }
+
+ /* Double-checked lock. */
+ std::lock_guard<std::mutex> lock(grids.mutex);
+ if (BKE_volume_is_loaded(volume)) {
+ return grids.error_msg.empty();
}
/* Get absolute file path. */
STRNCPY(grids.filepath, volume->filepath);
BLI_path_abs(grids.filepath, ID_BLEND_PATH(bmain, &volume->id));
- /* Initialize the first time we use it. This is thread safe and can be safely
- * called multiple times. */
- openvdb::initialize();
-
/* Open OpenVDB file. */
openvdb::io::File file(grids.filepath);
openvdb::GridPtrVec vdb_grids;
@@ -186,8 +215,11 @@ void BKE_volume_load(Volume *volume, Main *bmain)
volume->grids->emplace_back(vdb_grid, false);
}
}
+
+ return grids.error_msg.empty();
#else
UNUSED_VARS(bmain, volume);
+ return true;
#endif
}
@@ -226,11 +258,13 @@ BoundBox *BKE_volume_boundbox_get(Object *ob)
const int num_grids = BKE_volume_num_grids(volume);
for (int i = 0; i < num_grids; i++) {
+ VolumeGrid *grid = BKE_volume_grid_get(volume, i);
+ float grid_min[3], grid_max[3];
+
/* TODO: this is quite expensive, how often is it computed? Is there a faster
* way without actually reading grids? We should ensure copy-on-write does not
* compute this over and over for static files. */
- const VolumeGrid *grid = BKE_volume_grid_for_tree(volume, i);
- float grid_min[3], grid_max[3];
+ BKE_volume_grid_load(volume, grid);
if (BKE_volume_grid_bounds(grid, grid_min, grid_max)) {
DO_MIN(grid_min, min);
@@ -329,10 +363,15 @@ int BKE_volume_num_grids(Volume *volume)
const char *BKE_volume_grids_error_msg(const Volume *volume)
{
+#ifdef WITH_OPENVDB
return volume->grids->error_msg.c_str();
+#else
+ UNUSED_VARS(volume);
+ return "";
+#endif
}
-const VolumeGrid *BKE_volume_grid_for_metadata(Volume *volume, int grid_index)
+VolumeGrid *BKE_volume_grid_get(Volume *volume, int grid_index)
{
#ifdef WITH_OPENVDB
return &volume->grids->at(grid_index);
@@ -342,38 +381,75 @@ const VolumeGrid *BKE_volume_grid_for_metadata(Volume *volume, int grid_index)
#endif
}
-const VolumeGrid *BKE_volume_grid_for_tree(Volume *volume, int grid_index)
+VolumeGrid *BKE_volume_grid_find(Volume *volume, const char *name)
+{
+ int num_grids = BKE_volume_num_grids(volume);
+ for (int i = 0; i < num_grids; i++) {
+ VolumeGrid *grid = BKE_volume_grid_get(volume, i);
+ if (STREQ(BKE_volume_grid_name(grid), name)) {
+ return grid;
+ }
+ }
+
+ return NULL;
+}
+
+/* Grid Loading */
+
+bool BKE_volume_grid_load(Volume *volume, VolumeGrid *grid)
{
#ifdef WITH_OPENVDB
VolumeGridVector &grids = *volume->grids;
- VolumeGrid &grid = grids.at(grid_index);
-
- if (!grid.has_tree && grids.error_msg.empty()) {
- std::lock_guard<std::mutex> lock(grid.mutex);
-
- if (!grid.has_tree) {
- /* Read OpenVDB grid on-demand. */
- /* TODO: avoid repeating this for multiple grids when we know we will
- * need them? How best to do it without keeping the file open forever? */
- openvdb::io::File file(grids.filepath);
- openvdb::GridPtrVec vdb_grids;
-
- try {
- file.setCopyMaxBytes(0);
- file.open();
- grid.vdb = file.readGrid(grid.vdb->getName());
- grid.has_tree = true;
- }
- catch (const openvdb::IoError &e) {
- grids.error_msg = e.what();
- }
- }
+
+ if (BKE_volume_grid_is_loaded(grid)) {
+ return grids.error_msg.empty();
+ }
+
+ /* Double-checked lock. */
+ std::lock_guard<std::mutex> lock(grid->mutex);
+ if (BKE_volume_grid_is_loaded(grid)) {
+ return grids.error_msg.empty();
+ }
+
+ /* Read OpenVDB grid on-demand. */
+ /* TODO: avoid repeating this for multiple g
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list