diff options
Diffstat (limited to 'extern/mantaflow/preprocessed/fileio/iovdb.cpp')
-rw-r--r-- | extern/mantaflow/preprocessed/fileio/iovdb.cpp | 120 |
1 files changed, 93 insertions, 27 deletions
diff --git a/extern/mantaflow/preprocessed/fileio/iovdb.cpp b/extern/mantaflow/preprocessed/fileio/iovdb.cpp index 287c78f0608..8aca19ade04 100644 --- a/extern/mantaflow/preprocessed/fileio/iovdb.cpp +++ b/extern/mantaflow/preprocessed/fileio/iovdb.cpp @@ -31,6 +31,8 @@ # include "openvdb/openvdb.h" # include <openvdb/points/PointConversion.h> # include <openvdb/points/PointCount.h> +# include <openvdb/tools/Clip.h> +# include <openvdb/tools/Dense.h> #endif #define POSITION_NAME "P" @@ -45,15 +47,29 @@ namespace Manta { template<class GridType, class T> void importVDB(typename GridType::Ptr from, Grid<T> *to) { using ValueT = typename GridType::ValueType; - typename GridType::Accessor accessor = from->getAccessor(); - FOR_IJK(*to) - { - openvdb::Coord xyz(i, j, k); - ValueT vdbValue = accessor.getValue(xyz); - T toMantaValue; - convertFrom(vdbValue, &toMantaValue); - to->set(i, j, k, toMantaValue); + // 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); + } + } + // When importing all grid cells, using a grid accessor is usually faster than a value iterator + else { + typename GridType::Accessor accessor = from->getAccessor(); + FOR_IJK(*to) + { + openvdb::Coord xyz(i, j, k); + ValueT vdbValue = accessor.getValue(xyz); + T toMantaValue; + convertFrom(vdbValue, &toMantaValue); + to->set(i, j, k, toMantaValue); + } } } @@ -173,19 +189,43 @@ static void setGridOptions(typename GridType::Ptr grid, grid->setSaveFloatAsHalf(precision == PRECISION_MINI || precision == PRECISION_HALF); } -template<class T, class GridType> typename GridType::Ptr exportVDB(Grid<T> *from) +template<class T, class GridType> +typename GridType::Ptr exportVDB(Grid<T> *from, float clip, openvdb::FloatGrid::Ptr clipGrid) { using ValueT = typename GridType::ValueType; - typename GridType::Ptr to = GridType::create(); - typename GridType::Accessor accessor = to->getAccessor(); - - FOR_IJK(*from) - { - openvdb::Coord xyz(i, j, k); - T fromMantaValue = (*from)(i, j, k); - ValueT vdbValue; - convertTo(&vdbValue, fromMantaValue); - accessor.setValue(xyz, vdbValue); + typename GridType::Ptr to = GridType::create(ValueT(0)); + + // Copy data from grid by creating a vdb dense structure and then copying that into a vdb grid + // This is the fastest way to copy data for both dense and sparse grids -> if (true) + if (true) { + ValueT *data = (ValueT *)from->getData(); + openvdb::math::CoordBBox bbox( + openvdb::Coord(0), + openvdb::Coord(from->getSizeX() - 1, from->getSizeY() - 1, from->getSizeZ() - 1)); + openvdb::tools::Dense<ValueT, openvdb::tools::MemoryLayout::LayoutXYZ> dense(bbox, data); + + // Trick: Set clip value to very small / negative value in order to copy all values of dense + // grids + float tmpClip = (from->saveSparse()) ? clip : -std::numeric_limits<Real>::max(); + // Copy from dense to sparse grid structure considering clip value + openvdb::tools::copyFromDense(dense, *to, ValueT(tmpClip)); + + // If present, use clip grid to trim down current vdb grid even more + if (from->saveSparse() && clipGrid && !clipGrid->empty()) { + to = openvdb::tools::clip(*to, *clipGrid); + } + } + // Alternatively, reading all grid cells with an accessor (slightly slower) is possible like this + else { + typename GridType::Accessor accessor = to->getAccessor(); + FOR_IJK(*from) + { + openvdb::Coord xyz(i, j, k); + T fromMantaValue = (*from)(i, j, k); + ValueT vdbValue; + convertTo(&vdbValue, fromMantaValue); + accessor.setValue(xyz, vdbValue); + } } return to; } @@ -346,7 +386,9 @@ int writeObjectsVDB(const string &filename, float worldSize, bool skipDeletedParts, int compression, - int precision) + int precision, + float clip, + const Grid<Real> *clipGrid) { openvdb::initialize(); openvdb::io::File file(filename); @@ -357,6 +399,19 @@ int writeObjectsVDB(const string &filename, std::vector<ParticleDataBase *> pdbBuffer; + // Convert given clip grid to vdb clip grid + openvdb::FloatGrid::Ptr vdbClipGrid = nullptr; + if (clipGrid) { + vdbClipGrid = openvdb::FloatGrid::create(); + Real *data = (Real *)clipGrid->getData(); + openvdb::math::CoordBBox bbox(openvdb::Coord(0), + openvdb::Coord(clipGrid->getSizeX() - 1, + clipGrid->getSizeY() - 1, + clipGrid->getSizeZ() - 1)); + openvdb::tools::Dense<float, openvdb::tools::MemoryLayout::LayoutXYZ> dense(bbox, data); + openvdb::tools::copyFromDense(dense, *vdbClipGrid, clip); + } + for (std::vector<PbClass *>::iterator iter = objects->begin(); iter != objects->end(); ++iter) { openvdb::GridClass gClass = openvdb::GRID_UNKNOWN; openvdb::GridBase::Ptr vdbGrid; @@ -368,10 +423,14 @@ int writeObjectsVDB(const string &filename, if (GridBase *mantaGrid = dynamic_cast<GridBase *>(*iter)) { + if (clipGrid) { + assertMsg(clipGrid->getSize() == mantaGrid->getSize(), + "writeObjectsVDB: Clip grid and exported grid must have the same size"); + } if (mantaGrid->getType() & GridBase::TypeInt) { debMsg("Writing int grid '" << mantaGrid->getName() << "' to vdb file " << filename, 1); Grid<int> *mantaIntGrid = (Grid<int> *)mantaGrid; - vdbGrid = exportVDB<int, openvdb::Int32Grid>(mantaIntGrid); + vdbGrid = exportVDB<int, openvdb::Int32Grid>(mantaIntGrid, clip, vdbClipGrid); gridsVDB.push_back(vdbGrid); } else if (mantaGrid->getType() & GridBase::TypeReal) { @@ -379,7 +438,9 @@ int writeObjectsVDB(const string &filename, gClass = (mantaGrid->getType() & GridBase::TypeLevelset) ? openvdb::GRID_LEVEL_SET : openvdb::GRID_FOG_VOLUME; Grid<Real> *mantaRealGrid = (Grid<Real> *)mantaGrid; - vdbGrid = exportVDB<Real, openvdb::FloatGrid>(mantaRealGrid); + // Only supply clip grid if real grid is not equal to the clip grid + openvdb::FloatGrid::Ptr tmpClipGrid = (mantaRealGrid == clipGrid) ? nullptr : vdbClipGrid; + vdbGrid = exportVDB<Real, openvdb::FloatGrid>(mantaRealGrid, clip, tmpClipGrid); gridsVDB.push_back(vdbGrid); } else if (mantaGrid->getType() & GridBase::TypeVec3) { @@ -387,7 +448,7 @@ int writeObjectsVDB(const string &filename, gClass = (mantaGrid->getType() & GridBase::TypeMAC) ? openvdb::GRID_STAGGERED : openvdb::GRID_UNKNOWN; Grid<Vec3> *mantaVec3Grid = (Grid<Vec3> *)mantaGrid; - vdbGrid = exportVDB<Vec3, openvdb::Vec3SGrid>(mantaVec3Grid); + vdbGrid = exportVDB<Vec3, openvdb::Vec3SGrid>(mantaVec3Grid, clip, vdbClipGrid); gridsVDB.push_back(vdbGrid); } else { @@ -620,9 +681,12 @@ template void importVDB<openvdb::Int32Grid, int>(openvdb::Int32Grid::Ptr from, G template void importVDB<openvdb::FloatGrid, Real>(openvdb::FloatGrid::Ptr from, Grid<Real> *to); template void importVDB<openvdb::Vec3SGrid, Vec3>(openvdb::Vec3SGrid::Ptr from, Grid<Vec3> *to); -template openvdb::Int32Grid::Ptr exportVDB<int, openvdb::Int32Grid>(Grid<int> *from); -template openvdb::FloatGrid::Ptr exportVDB<Real, openvdb::FloatGrid>(Grid<Real> *from); -template openvdb::Vec3SGrid::Ptr exportVDB<Vec3, openvdb::Vec3SGrid>(Grid<Vec3> *from); +template openvdb::Int32Grid::Ptr exportVDB<int, openvdb::Int32Grid>( + Grid<int> *from, float clip = 1e-4, openvdb::FloatGrid::Ptr clipGrid = nullptr); +template openvdb::FloatGrid::Ptr exportVDB<Real, openvdb::FloatGrid>( + Grid<Real> *from, float clip = 1e-4, openvdb::FloatGrid::Ptr clipGrid = nullptr); +template openvdb::Vec3SGrid::Ptr exportVDB<Vec3, openvdb::Vec3SGrid>( + Grid<Vec3> *from, float clip = 1e-4, openvdb::FloatGrid::Ptr clipGrid = nullptr); openvdb::points::PointDataGrid::Ptr exportVDB(BasicParticleSystem *from, std::vector<ParticleDataBase *> &fromPData, @@ -652,7 +716,9 @@ int writeObjectsVDB(const string &filename, float worldSize, bool skipDeletedParts, int compression, - int precision) + int precision, + float clip, + const Grid<Real> *clipGrid) { errMsg("Cannot save to .vdb file. Mantaflow has not been built with OpenVDB support."); return 0; |