diff --git a/extern/mantaflow/README.blender b/extern/mantaflow/README.blender index 2fea9511b25..1d11159f4d4 100644 --- a/extern/mantaflow/README.blender +++ b/extern/mantaflow/README.blender @@ -7,6 +7,7 @@ Local modifications: * ./patches/local_namespace.diff to support loading MANTA variables into an isolated __main__ name-space. * ./patches/fix-computation-errors.patch to fix computation errors for normalization functions for 3d vectors by using std::hypot. * ./patches/fluid-viscosity-performance.patch improve fluid viscosity performance by moving var checking outside loop. +* ./patches/import-openvdb-empty-cubes-fix.patch to fix OpenVDB import visual glitches, by copying full 8x8x8 nodes. * ./patches/precision-of-4d-vector.patch to increase precision of 4D vector normalization functions. * ./patches/liquid-mesh-performance.patch improve liquid mesh generation by puting calculation of inverse radius outside for loops. * ./patches/liquid-performance.patch improve liquid generation (without mesh) by precalculate sum of vectors and put it outside for loop. diff --git a/extern/mantaflow/patches/import-openvdb-empty-cubes-fix.patch b/extern/mantaflow/patches/import-openvdb-empty-cubes-fix.patch new file mode 100644 index 00000000000..7067ad6562e --- /dev/null +++ b/extern/mantaflow/patches/import-openvdb-empty-cubes-fix.patch @@ -0,0 +1,46 @@ +commit 725df6eb883dadf2225938baecf97c005da5b549 +Author: Bartosz Kosiorek +Date: Wed May 21 22:44:01 2025 +0200 + + Physics: Fix OpenVDB import visual glitches, by copying full 8x8x8 nodes + + If grid has 8x8x8 block with the same value, it is stored as Tile with single value. + We need to iterate over the bounding box and copy such value to all voxels in 8x8x8 node. + + Fixes: #91174 #124064 + +diff --git a/extern/mantaflow/preprocessed/fileio/iovdb.cpp b/extern/mantaflow/preprocessed/fileio/iovdb.cpp +index 4b7463782da..85ab3781e5a 100644 +--- a/extern/mantaflow/preprocessed/fileio/iovdb.cpp ++++ b/extern/mantaflow/preprocessed/fileio/iovdb.cpp +@@ -54,14 +54,28 @@ template void importVDB(typename GridType::Ptr from, Gr + using ValueT = typename GridType::ValueType; + + // Check if current grid is to be read as a sparse grid, active voxels (only) will be copied ++ + if (to->saveSparse()) { + to->clear(); // Ensure that destination grid is empty before writing + for (typename GridType::ValueOnCIter iter = from->cbeginValueOn(); iter.test(); ++iter) { + ValueT vdbValue = *iter; +- openvdb::Coord coord = iter.getCoord(); + T toMantaValue; + convertFrom(vdbValue, &toMantaValue); +- to->set(coord.x(), coord.y(), coord.z(), toMantaValue); ++ // #91174 #124064 - Check if iteration is Voxel or Tile ++ if (iter.isVoxelValue()) { ++ openvdb::Coord coord = iter.getCoord(); ++ to->set(coord.x(), coord.y(), coord.z(), toMantaValue); ++ } ++ else { ++ openvdb::CoordBBox bbox; ++ iter.getBoundingBox(bbox); ++ // If grid has 8x8x8 block with the same value, it is stored as Tile with single value. ++ // We need to iterate over the bounding box and copy such value to all voxels in 8x8x8 node. ++ for (openvdb::CoordBBox::Iterator ijk(bbox); ijk; ++ijk) { ++ openvdb::Coord coord = *ijk; ++ to->set(coord.x(), coord.y(), coord.z(), toMantaValue); ++ } ++ } + } + } + // When importing all grid cells, using a grid accessor is usually faster than a value iterator diff --git a/extern/mantaflow/preprocessed/fileio/iovdb.cpp b/extern/mantaflow/preprocessed/fileio/iovdb.cpp index 4b7463782da..85ab3781e5a 100644 --- a/extern/mantaflow/preprocessed/fileio/iovdb.cpp +++ b/extern/mantaflow/preprocessed/fileio/iovdb.cpp @@ -54,14 +54,28 @@ template void importVDB(typename GridType::Ptr from, Gr using ValueT = typename GridType::ValueType; // Check if current grid is to be read as a sparse grid, active voxels (only) will be copied + if (to->saveSparse()) { to->clear(); // Ensure that destination grid is empty before writing for (typename GridType::ValueOnCIter iter = from->cbeginValueOn(); iter.test(); ++iter) { ValueT vdbValue = *iter; - openvdb::Coord coord = iter.getCoord(); T toMantaValue; convertFrom(vdbValue, &toMantaValue); - to->set(coord.x(), coord.y(), coord.z(), toMantaValue); + // #91174 #124064 - Check if iteration is Voxel or Tile + if (iter.isVoxelValue()) { + openvdb::Coord coord = iter.getCoord(); + to->set(coord.x(), coord.y(), coord.z(), toMantaValue); + } + else { + openvdb::CoordBBox bbox; + iter.getBoundingBox(bbox); + // If grid has 8x8x8 block with the same value, it is stored as Tile with single value. + // We need to iterate over the bounding box and copy such value to all voxels in 8x8x8 node. + for (openvdb::CoordBBox::Iterator ijk(bbox); ijk; ++ijk) { + openvdb::Coord coord = *ijk; + to->set(coord.x(), coord.y(), coord.z(), toMantaValue); + } + } } } // When importing all grid cells, using a grid accessor is usually faster than a value iterator