Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJacques Lucke <jacques@blender.org>2022-08-29 18:00:08 +0300
committerJacques Lucke <jacques@blender.org>2022-08-29 18:00:08 +0300
commite3a6a2f41284f90b01065309dbe2cfb97a292b41 (patch)
tree0f310fa0c9d90d9e88a7ddd57429f8276d64ec7d /source/blender/blenkernel
parent7bb08882ecec93048bf04d36c7baabd31f341c7a (diff)
Fix T99004: scaling volume down results in crash
OpenVDB crashes when the determinant of the grid transformation is too small. The solution is too detect when the determinant is too small and to replace the grid with an empty one. If possible the translation and rotation of the grid remains unchanged. Differential Revision: https://developer.blender.org/D15806
Diffstat (limited to 'source/blender/blenkernel')
-rw-r--r--source/blender/blenkernel/BKE_volume.h9
-rw-r--r--source/blender/blenkernel/intern/volume.cc47
2 files changed, 56 insertions, 0 deletions
diff --git a/source/blender/blenkernel/BKE_volume.h b/source/blender/blenkernel/BKE_volume.h
index bc578ef8b28..4215cad5858 100644
--- a/source/blender/blenkernel/BKE_volume.h
+++ b/source/blender/blenkernel/BKE_volume.h
@@ -114,6 +114,7 @@ int BKE_volume_grid_channels(const struct VolumeGrid *grid);
* Transformation from index space to object space.
*/
void BKE_volume_grid_transform_matrix(const struct VolumeGrid *grid, float mat[4][4]);
+void BKE_volume_grid_transform_matrix_set(struct VolumeGrid *volume_grid, const float mat[4][4]);
/* Volume Editing
*
@@ -133,6 +134,11 @@ struct VolumeGrid *BKE_volume_grid_add(struct Volume *volume,
VolumeGridType type);
void BKE_volume_grid_remove(struct Volume *volume, struct VolumeGrid *grid);
+/**
+ * Openvdb crashes when the determinant of the transform matrix becomes too small.
+ */
+bool BKE_volume_grid_determinant_valid(double determinant);
+
/* Simplify */
int BKE_volume_simplify_level(const struct Depsgraph *depsgraph);
float BKE_volume_simplify_factor(const struct Depsgraph *depsgraph);
@@ -186,6 +192,9 @@ openvdb::GridBase::Ptr BKE_volume_grid_openvdb_for_write(const struct Volume *vo
struct VolumeGrid *grid,
bool clear);
+void BKE_volume_grid_clear_tree(Volume &volume, VolumeGrid &volume_grid);
+void BKE_volume_grid_clear_tree(openvdb::GridBase &grid);
+
VolumeGridType BKE_volume_grid_type_openvdb(const openvdb::GridBase &grid);
template<typename OpType>
diff --git a/source/blender/blenkernel/intern/volume.cc b/source/blender/blenkernel/intern/volume.cc
index 2f5bf0de58f..6ba396259aa 100644
--- a/source/blender/blenkernel/intern/volume.cc
+++ b/source/blender/blenkernel/intern/volume.cc
@@ -1361,6 +1361,26 @@ const char *BKE_volume_grid_name(const VolumeGrid *volume_grid)
}
#ifdef WITH_OPENVDB
+struct ClearGridOp {
+ openvdb::GridBase &grid;
+
+ template<typename Grid> void operator()()
+ {
+ static_cast<Grid &>(grid).clear();
+ }
+};
+void BKE_volume_grid_clear_tree(openvdb::GridBase &grid)
+{
+ const VolumeGridType grid_type = BKE_volume_grid_type_openvdb(grid);
+ ClearGridOp op{grid};
+ BKE_volume_grid_type_operation(grid_type, op);
+}
+void BKE_volume_grid_clear_tree(Volume &volume, VolumeGrid &volume_grid)
+{
+ openvdb::GridBase::Ptr grid = BKE_volume_grid_openvdb_for_write(&volume, &volume_grid, false);
+ BKE_volume_grid_clear_tree(*grid);
+}
+
VolumeGridType BKE_volume_grid_type_openvdb(const openvdb::GridBase &grid)
{
if (grid.isType<openvdb::FloatGrid>()) {
@@ -1451,6 +1471,23 @@ void BKE_volume_grid_transform_matrix(const VolumeGrid *volume_grid, float mat[4
#endif
}
+void BKE_volume_grid_transform_matrix_set(struct VolumeGrid *volume_grid, const float mat[4][4])
+{
+#ifdef WITH_OPENVDB
+ openvdb::math::Mat4f mat_openvdb;
+ for (int col = 0; col < 4; col++) {
+ for (int row = 0; row < 4; row++) {
+ mat_openvdb(col, row) = mat[col][row];
+ }
+ }
+ openvdb::GridBase::Ptr grid = volume_grid->grid();
+ grid->setTransform(std::make_shared<openvdb::math::Transform>(
+ std::make_shared<openvdb::math::AffineMap>(mat_openvdb)));
+#else
+ UNUSED_VARS(grid, mat);
+#endif
+}
+
/* Grid Tree and Voxels */
/* Volume Editing */
@@ -1547,6 +1584,16 @@ void BKE_volume_grid_remove(Volume *volume, VolumeGrid *grid)
#endif
}
+bool BKE_volume_grid_determinant_valid(const double determinant)
+{
+#ifdef WITH_OPENVDB
+ /* Limit taken from openvdb/math/Maps.h. */
+ return std::abs(determinant) >= 3.0 * openvdb::math::Tolerance<double>::value();
+#else
+ return true;
+#endif
+}
+
int BKE_volume_simplify_level(const Depsgraph *depsgraph)
{
if (DEG_get_mode(depsgraph) != DAG_EVAL_RENDER) {