[Bf-blender-cvs] [b6f49ec208d] new-object-types: Volumes: API functions to modify grids in the modifiers stack
Brecht Van Lommel
noreply at git.blender.org
Mon Feb 10 14:37:58 CET 2020
Commit: b6f49ec208d91da29c6fb1e67b5f37308c10b666
Author: Brecht Van Lommel
Date: Sun Feb 9 17:25:11 2020 +0100
Branches: new-object-types
https://developer.blender.org/rBb6f49ec208d91da29c6fb1e67b5f37308c10b666
Volumes: API functions to modify grids in the modifiers stack
===================================================================
M source/blender/blenkernel/BKE_volume.h
M source/blender/blenkernel/intern/volume.cc
===================================================================
diff --git a/source/blender/blenkernel/BKE_volume.h b/source/blender/blenkernel/BKE_volume.h
index a76996afe20..cf0260b417b 100644
--- a/source/blender/blenkernel/BKE_volume.h
+++ b/source/blender/blenkernel/BKE_volume.h
@@ -60,9 +60,6 @@ struct BoundBox *BKE_volume_boundbox_get(struct Object *ob);
/* Depsgraph */
-struct Volume *BKE_volume_new_for_eval(const struct Volume *volume_src);
-struct Volume *BKE_volume_copy_for_eval(struct Volume *volume_src, bool reference);
-
void BKE_volume_eval_geometry(struct Depsgraph *depsgraph, struct Volume *volume);
void BKE_volume_data_update(struct Depsgraph *depsgraph,
struct Scene *scene,
@@ -105,7 +102,7 @@ VolumeGrid *BKE_volume_grid_find(struct Volume *volume, const char *name);
/* Grid
*
* By default only grid metadata is loaded, for access to the tree and voxels
- * the BKE_volume_grid_load must be called first. */
+ * BKE_volume_grid_load must be called first. */
typedef enum VolumeGridType {
VOLUME_GRID_UNKNOWN = 0,
@@ -146,8 +143,44 @@ void BKE_volume_grid_dense_voxels(const struct VolumeGrid *volume_grid,
const size_t max[3],
float *voxels);
+/* Volume Editing
+ *
+ * These are intended for modifiers to use on evaluated datablocks.
+ *
+ * new_for_eval creates a volume datablock with no grids or file path, but
+ * preserves other settings such as viewport display options.
+ *
+ * copy_for_eval creates a volume datablock preserving everything except the
+ * file path. Grids are shared with the source datablock, not copied.
+ *
+ * Before modifying grids after copy_for_eval, call ensure_writable first.
+ * It will duplicate (or clear) the grid if it is shared with any other
+ * datablocks, so that it can be safely modified. */
+
+struct Volume *BKE_volume_new_for_eval(const struct Volume *volume_src);
+struct Volume *BKE_volume_copy_for_eval(struct Volume *volume_src, bool reference);
+
+struct VolumeGrid *BKE_volume_grid_add(struct Volume *volume,
+ const char *name,
+ VolumeGridType type);
+void BKE_volume_grid_remove(struct Volume *volume, struct VolumeGrid *grid);
+void BKE_volume_grid_ensure_writable(struct Volume *volume,
+ struct VolumeGrid *grid,
+ const bool clear);
+
#ifdef __cplusplus
}
#endif
+/* OpenVDB Grid
+ *
+ * Access to OpenVDB grid for C++. This will call BKE_volume_grid_load if the
+ * grid has not already been loaded into memory. */
+
+#if defined(__cplusplus) && defined(WITH_OPENVDB)
+# include <openvdb/openvdb.h>
+openvdb::GridBase::Ptr BKE_volume_grid_ensure_openvdb(struct Volume *volume,
+ struct VolumeGrid *grid);
+#endif
+
#endif
diff --git a/source/blender/blenkernel/intern/volume.cc b/source/blender/blenkernel/intern/volume.cc
index dfc485596a5..a5622323f68 100644
--- a/source/blender/blenkernel/intern/volume.cc
+++ b/source/blender/blenkernel/intern/volume.cc
@@ -58,6 +58,7 @@ static CLG_LogRef LOG = {"bke.volume"};
#ifdef WITH_OPENVDB
# include <atomic>
+# include <list>
# include <mutex>
# include <unordered_set>
@@ -328,6 +329,31 @@ struct VolumeGrid {
is_loaded = false;
}
+ void clear_reference(const char *UNUSED(volume_name))
+ {
+ /* Clear any reference to a grid in the file cache. */
+ vdb = vdb->copyGridWithNewTree();
+ if (entry) {
+ GLOBAL_CACHE.remove_user(*entry, is_loaded);
+ entry = NULL;
+ }
+ is_loaded = true;
+ }
+
+ void duplicate_reference(const char *volume_name, const char *filepath)
+ {
+ /* Make a deep copy of the grid and remove any reference to a grid in the
+ * file cache. Load file grid into memory first if needed. */
+ load(volume_name, filepath);
+ // TODO: avoid deep copy if we are the only user
+ vdb = vdb->deepCopyGrid();
+ if (entry) {
+ GLOBAL_CACHE.remove_user(*entry, is_loaded);
+ entry = NULL;
+ }
+ is_loaded = true;
+ }
+
const char *name() const
{
/* Don't use vdb.getName() since it copies the string, we want a pointer to the
@@ -362,7 +388,7 @@ struct VolumeGrid {
* List of grids contained in a volume datablock. This is runtime-only data,
* the actual grids are always saved in a VDB file. */
-struct VolumeGridVector : public std::vector<VolumeGrid> {
+struct VolumeGridVector : public std::list<VolumeGrid> {
VolumeGridVector()
{
filepath[0] = '\0';
@@ -710,33 +736,6 @@ BoundBox *BKE_volume_boundbox_get(Object *ob)
/* Dependency Graph */
-Volume *BKE_volume_new_for_eval(const Volume *volume_src)
-{
- Volume *volume_dst = (Volume *)BKE_id_new_nomain(ID_VO, NULL);
-
- STRNCPY(volume_dst->id.name, volume_src->id.name);
- volume_dst->mat = (Material **)MEM_dupallocN(volume_src->mat);
- volume_dst->totcol = volume_src->totcol;
- BKE_volume_init_grids(volume_dst);
-
- return volume_dst;
-}
-
-Volume *BKE_volume_copy_for_eval(Volume *volume_src, bool reference)
-{
- int flags = LIB_ID_COPY_LOCALIZE;
-
- if (reference) {
- flags |= LIB_ID_COPY_CD_REFERENCE;
- }
-
- Volume *result;
- BKE_id_copy_ex(NULL, &volume_src->id, (ID **)&result, flags);
- result->filepath[0] = '\0';
-
- return result;
-}
-
static Volume *volume_evaluate_modifiers(struct Depsgraph *depsgraph,
struct Scene *scene,
Object *object,
@@ -886,7 +885,13 @@ const char *BKE_volume_grids_error_msg(const Volume *volume)
VolumeGrid *BKE_volume_grid_get(Volume *volume, int grid_index)
{
#ifdef WITH_OPENVDB
- return &volume->runtime.grids->at(grid_index);
+ VolumeGridVector &grids = *volume->runtime.grids;
+ for (VolumeGrid &grid : grids) {
+ if (grid_index-- == 0) {
+ return &grid;
+ }
+ }
+ return NULL;
#else
UNUSED_VARS(volume, grid_index);
return NULL;
@@ -1226,3 +1231,122 @@ void BKE_volume_grid_dense_voxels(const VolumeGrid *volume_grid,
UNUSED_VARS(volume_grid, min, max, voxels);
#endif
}
+
+/* Volume Editing */
+
+Volume *BKE_volume_new_for_eval(const Volume *volume_src)
+{
+ Volume *volume_dst = (Volume *)BKE_id_new_nomain(ID_VO, NULL);
+
+ STRNCPY(volume_dst->id.name, volume_src->id.name);
+ volume_dst->mat = (Material **)MEM_dupallocN(volume_src->mat);
+ volume_dst->totcol = volume_src->totcol;
+ BKE_volume_init_grids(volume_dst);
+
+ return volume_dst;
+}
+
+Volume *BKE_volume_copy_for_eval(Volume *volume_src, bool reference)
+{
+ int flags = LIB_ID_COPY_LOCALIZE;
+
+ if (reference) {
+ flags |= LIB_ID_COPY_CD_REFERENCE;
+ }
+
+ Volume *result;
+ BKE_id_copy_ex(NULL, &volume_src->id, (ID **)&result, flags);
+ result->filepath[0] = '\0';
+
+ return result;
+}
+
+VolumeGrid *BKE_volume_grid_add(Volume *volume, const char *name, VolumeGridType type)
+{
+#ifdef WITH_OPENVDB
+ VolumeGridVector &grids = *volume->runtime.grids;
+ BLI_assert(BKE_volume_grid_find(volume, name) == NULL);
+
+ openvdb::GridBase::Ptr vdb_grid;
+ switch (type) {
+ case VOLUME_GRID_FLOAT:
+ vdb_grid = openvdb::FloatGrid::create();
+ break;
+ case VOLUME_GRID_VECTOR_FLOAT:
+ vdb_grid = openvdb::Vec3fGrid::create();
+ break;
+ case VOLUME_GRID_BOOLEAN:
+ vdb_grid = openvdb::BoolGrid::create();
+ break;
+ case VOLUME_GRID_DOUBLE:
+ vdb_grid = openvdb::DoubleGrid::create();
+ break;
+ case VOLUME_GRID_INT:
+ vdb_grid = openvdb::Int32Grid::create();
+ break;
+ case VOLUME_GRID_INT64:
+ vdb_grid = openvdb::Int64Grid::create();
+ break;
+ case VOLUME_GRID_VECTOR_INT:
+ vdb_grid = openvdb::Vec3IGrid::create();
+ break;
+ case VOLUME_GRID_VECTOR_DOUBLE:
+ vdb_grid = openvdb::Vec3dGrid::create();
+ break;
+ case VOLUME_GRID_STRING:
+ vdb_grid = openvdb::StringGrid::create();
+ break;
+ case VOLUME_GRID_MASK:
+ vdb_grid = openvdb::MaskGrid::create();
+ break;
+ case VOLUME_GRID_UNKNOWN:
+ return NULL;
+ }
+
+ vdb_grid->setName(name);
+ grids.emplace_back(vdb_grid);
+ return &grids.back();
+#else
+ UNUSED_VARS(volume, name, type);
+ return NULL;
+#endif
+}
+
+void BKE_volume_grid_remove(Volume *volume, VolumeGrid *grid)
+{
+#ifdef WITH_OPENVDB
+ VolumeGridVector &grids = *volume->runtime.grids;
+ for (VolumeGridVector::iterator it = grids.begin(); it != grids.end(); it++) {
+ if (&*it == grid) {
+ grids.erase(it);
+ break;
+ }
+ }
+#else
+ UNUSED_VARS(volume, grid);
+#endif
+}
+
+void BKE_volume_grid_ensure_writable(Volume *volume, VolumeGrid *grid, bool clear)
+{
+#ifdef WITH_OPENVDB
+ const char *volume_name = volume->id.name + 2;
+ if (clear) {
+ grid->clear_reference(volume_name);
+ }
+ else {
+ VolumeGridVector &grids = *volume->runtime.grids;
+ grid->duplicate_reference(volume_name, grids.filepath);
+ }
+#else
+ UNUSED_VARS(volume, grid);
+#endif
+}
+
+#ifdef WITH_OPENVDB
+openvdb::GridBase::Ptr BKE_volume_grid_ensure_openvdb(Volume *volume, VolumeGrid *grid)
+{
+ BKE_volume_grid_load(volume, grid);
+ return grid->vdb;
+}
+#endif
More information about the Bf-blender-cvs
mailing list