From 9fe64948abe991d18c1af3a52d81e87c24d39687 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebasti=C3=A1n=20Barschkis?= Date: Wed, 24 Jun 2020 12:00:13 +0200 Subject: Fluid: Updated Mantaflow source with latest OpenVDB changes This updated set of Mantaflow files includes the improved OpenVDB file IO. With this update it is finally possible to store multiple grids per file. It is also possible to save particle systems and particle data to OpenVDB files. --- extern/mantaflow/preprocessed/fileio/iogrids.cpp | 565 +++++++------------ extern/mantaflow/preprocessed/fileio/iomeshes.cpp | 74 ++- .../mantaflow/preprocessed/fileio/ioparticles.cpp | 49 +- extern/mantaflow/preprocessed/fileio/ioutil.cpp | 56 +- extern/mantaflow/preprocessed/fileio/iovdb.cpp | 618 +++++++++++++++++++++ extern/mantaflow/preprocessed/fileio/mantaio.cpp | 144 +++++ extern/mantaflow/preprocessed/fileio/mantaio.h | 110 ++-- 7 files changed, 1173 insertions(+), 443 deletions(-) create mode 100644 extern/mantaflow/preprocessed/fileio/iovdb.cpp create mode 100644 extern/mantaflow/preprocessed/fileio/mantaio.cpp (limited to 'extern/mantaflow/preprocessed/fileio') diff --git a/extern/mantaflow/preprocessed/fileio/iogrids.cpp b/extern/mantaflow/preprocessed/fileio/iogrids.cpp index acd1bda5174..e2550d6db8b 100644 --- a/extern/mantaflow/preprocessed/fileio/iogrids.cpp +++ b/extern/mantaflow/preprocessed/fileio/iogrids.cpp @@ -27,10 +27,6 @@ extern "C" { } #endif -#if OPENVDB == 1 -# include "openvdb/openvdb.h" -#endif - #include "cnpy.h" #include "mantaio.h" #include "grid.h" @@ -279,54 +275,87 @@ static int unifyGridType(int type) // grid data //***************************************************************************** -template void writeGridTxt(const string &name, Grid *grid) +template int writeGridTxt(const string &name, Grid *grid) { debMsg("writing grid " << grid->getName() << " to text file " << name, 1); ofstream ofs(name.c_str()); if (!ofs.good()) errMsg("writeGridTxt: can't open file " << name); + return 0; FOR_IJK(*grid) { ofs << Vec3i(i, j, k) << " = " << (*grid)(i, j, k) << "\n"; } ofs.close(); + return 1; +} + +int writeGridsTxt(const string &name, std::vector *grids) +{ + errMsg("writeGridsTxt: writing multiple grids to one .txt file not supported yet"); + return 0; } -template void writeGridRaw(const string &name, Grid *grid) +int readGridsTxt(const string &name, std::vector *grids) +{ + errMsg("readGridsTxt: writing multiple grids from one .txt file not supported yet"); + return 0; +} + +template int writeGridRaw(const string &name, Grid *grid) { debMsg("writing grid " << grid->getName() << " to raw file " << name, 1); #if NO_ZLIB != 1 gzFile gzf = (gzFile)safeGzopen(name.c_str(), "wb1"); // do some compression - if (!gzf) + if (!gzf) { errMsg("writeGridRaw: can't open file " << name); + return 0; + } + gzwrite(gzf, &((*grid)[0]), sizeof(T) * grid->getSizeX() * grid->getSizeY() * grid->getSizeZ()); - gzclose(gzf); + return (gzclose(gzf) == Z_OK); #else debMsg("file format not supported without zlib", 1); + return 0; #endif } -template void readGridRaw(const string &name, Grid *grid) +template int readGridRaw(const string &name, Grid *grid) { debMsg("reading grid " << grid->getName() << " from raw file " << name, 1); #if NO_ZLIB != 1 gzFile gzf = (gzFile)safeGzopen(name.c_str(), "rb"); - if (!gzf) + if (!gzf) { errMsg("readGridRaw: can't open file " << name); + return 0; + } IndexInt bytes = sizeof(T) * grid->getSizeX() * grid->getSizeY() * grid->getSizeZ(); IndexInt readBytes = gzread(gzf, &((*grid)[0]), bytes); assertMsg(bytes == readBytes, "can't read raw file, stream length does not match, " << bytes << " vs " << readBytes); - gzclose(gzf); + return (gzclose(gzf) == Z_OK); #else debMsg("file format not supported without zlib", 1); + return 0; #endif } +int writeGridsRaw(const string &name, std::vector *grids) +{ + errMsg("writeGridsRaw: writing multiple grids to one .raw file not supported yet"); + return 0; +} + +int readGridsRaw(const string &name, std::vector *grids) +{ + errMsg("readGridsRaw: reading multiple grids from one .raw file not supported yet"); + return 0; +} + //! legacy headers for reading old files typedef struct { int dimX, dimY, dimZ; @@ -473,7 +502,7 @@ void PbRegister_printUniFileInfoString() // actual read/write functions -template void writeGridUni(const string &name, Grid *grid) +template int writeGridUni(const string &name, Grid *grid) { debMsg("Writing grid " << grid->getName() << " to uni file " << name, 1); @@ -496,12 +525,16 @@ template void writeGridUni(const string &name, Grid *grid) head.elementType = 1; else if (grid->getType() & GridBase::TypeVec3) head.elementType = 2; - else + else { errMsg("writeGridUni: unknown element type"); + return 0; + } gzFile gzf = (gzFile)safeGzopen(name.c_str(), "wb1"); // do some compression - if (!gzf) + if (!gzf) { errMsg("writeGridUni: can't open file " << name); + return 0; + } gzwrite(gzf, ID, 4); # if FLOATINGPOINT_PRECISION != 1 @@ -515,21 +548,24 @@ template void writeGridUni(const string &name, Grid *grid) gzwrite(gzf, &head, sizeof(UniHeader)); gzwrite(gzf, ptr, sizeof(T) * head.dimX * head.dimY * head.dimZ); # endif - gzclose(gzf); + return (gzclose(gzf) == Z_OK); #else debMsg("file format not supported without zlib", 1); + return 0; #endif }; -template void readGridUni(const string &name, Grid *grid) +template int readGridUni(const string &name, Grid *grid) { debMsg("Reading grid " << grid->getName() << " from uni file " << name, 1); #if NO_ZLIB != 1 gzFile gzf = (gzFile)safeGzopen(name.c_str(), "rb"); - if (!gzf) + if (!gzf) { errMsg("readGridUni: can't open file " << name); + return 0; + } char ID[5] = {0, 0, 0, 0, 0}; gzread(gzf, ID, 4); @@ -609,17 +645,44 @@ template void readGridUni(const string &name, Grid *grid) } else { errMsg("readGridUni: Unknown header '" << ID << "' "); + return 0; } - gzclose(gzf); + return (gzclose(gzf) == Z_OK); #else debMsg("file format not supported without zlib", 1); + return 0; #endif }; -template void writeGridVol(const string &name, Grid *grid) +int writeGridsUni(const string &name, std::vector *grids) +{ + errMsg("writeGridsUni: writing multiple grids to one .uni file not supported yet"); + return 0; +} + +int readGridsUni(const string &name, std::vector *grids) +{ + errMsg("readGridsUni: reading multiple grids from one .uni file not supported yet"); + return 0; +} + +template int writeGridVol(const string &name, Grid *grid) { debMsg("writing grid " << grid->getName() << " to vol file " << name, 1); errMsg("writeGridVol: Type not yet supported!"); + return 0; +} + +int writeGridsVol(const string &name, std::vector *grids) +{ + errMsg("writeGridsVol: writing multiple grids to one .vol file not supported yet"); + return 0; +} + +int readGridsVol(const string &name, std::vector *grids) +{ + errMsg("readGridsVol: reading multiple grids from one .vol file not supported yet"); + return 0; } struct volHeader { @@ -631,7 +694,7 @@ struct volHeader { Vec3 bboxMin, bboxMax; }; -template<> void writeGridVol(const string &name, Grid *grid) +template<> int writeGridVol(const string &name, Grid *grid) { debMsg("writing real grid " << grid->getName() << " to vol file " << name, 1); @@ -651,7 +714,7 @@ template<> void writeGridVol(const string &name, Grid *grid) FILE *fp = fopen(name.c_str(), "wb"); if (fp == NULL) { errMsg("writeGridVol: Cannot open '" << name << "'"); - return; + return 0; } fwrite(&header, sizeof(volHeader), 1, fp); @@ -667,17 +730,17 @@ template<> void writeGridVol(const string &name, Grid *grid) fwrite(&value, sizeof(float), 1, fp); } #endif - - fclose(fp); + return (!fclose(fp)); }; -template void readGridVol(const string &name, Grid *grid) +template int readGridVol(const string &name, Grid *grid) { debMsg("writing grid " << grid->getName() << " to vol file " << name, 1); errMsg("readGridVol: Type not yet supported!"); + return 0; } -template<> void readGridVol(const string &name, Grid *grid) +template<> int readGridVol(const string &name, Grid *grid) { debMsg("reading real grid " << grid->getName() << " from vol file " << name, 1); @@ -685,7 +748,7 @@ template<> void readGridVol(const string &name, Grid *grid) FILE *fp = fopen(name.c_str(), "rb"); if (fp == NULL) { errMsg("readGridVol: Cannot open '" << name << "'"); - return; + return 0; } // note, only very basic file format checks here! @@ -697,17 +760,17 @@ template<> void readGridVol(const string &name, Grid *grid) << grid->getSize()); #if FLOATINGPOINT_PRECISION != 1 errMsg("readGridVol: Double precision not yet supported"); + return 0; #else const unsigned int s = sizeof(float) * header.dimX * header.dimY * header.dimZ; assertMsg(fread(&((*grid)[0]), 1, s, fp) == s, "can't read file, no / not enough data"); #endif - - fclose(fp); + return (!fclose(fp)); }; // 4d grids IO -template void writeGrid4dUni(const string &name, Grid4d *grid) +template int writeGrid4dUni(const string &name, Grid4d *grid) { debMsg("writing grid4d " << grid->getName() << " to uni file " << name, 1); @@ -733,12 +796,16 @@ template void writeGrid4dUni(const string &name, Grid4d *grid) head.elementType = 2; else if (grid->getType() & Grid4dBase::TypeVec4) head.elementType = 2; - else + else { errMsg("writeGrid4dUni: unknown element type"); + return 0; + } gzFile gzf = (gzFile)safeGzopen(name.c_str(), "wb1"); // do some compression - if (!gzf) + if (!gzf) { errMsg("writeGrid4dUni: can't open file " << name); + return 0; + } gzwrite(gzf, ID, 4); # if FLOATINGPOINT_PRECISION != 1 @@ -753,16 +820,17 @@ template void writeGrid4dUni(const string &name, Grid4d *grid) gzwrite(gzf, ptr, sizeof(T) * head.dimX * head.dimY * head.dimZ * 1); } # endif - gzclose(gzf); + return (gzclose(gzf) == Z_OK); #else debMsg("file format not supported without zlib", 1); + return 0; #endif }; //! note, reading 4d uni grids is slightly more complicated than 3d ones //! as it optionally supports sliced reading template -void readGrid4dUni( +int readGrid4dUni( const string &name, Grid4d *grid, int readTslice, Grid4d *slice, void **fileHandle) { if (grid) @@ -779,8 +847,10 @@ void readGrid4dUni( // optionally - reuse file handle, if valid one is passed in fileHandle pointer... if ((!fileHandle) || (fileHandle && (*fileHandle == NULL))) { gzf = (gzFile)safeGzopen(name.c_str(), "rb"); - if (!gzf) + if (!gzf) { errMsg("readGrid4dUni: can't open file " << name); + return 0; + } gzread(gzf, ID, 4); if (fileHandle) { @@ -792,7 +862,7 @@ void readGrid4dUni( gzf = (gzFile)(*fileHandle); void *ptr = &((*slice)[0]); gzread(gzf, ptr, sizeof(T) * slice->getStrideT() * 1); // quick and dirty... - return; + return 1; } if ((!strcmp(ID, "M4T2")) || (!strcmp(ID, "M4T3"))) { @@ -867,6 +937,7 @@ void readGrid4dUni( # if FLOATINGPOINT_PRECISION != 1 errMsg("readGrid4dUni: NYI (2)"); // slice read not yet supported for double + return 0; # else assertMsg(slice, "No 3d slice grid data given"); assertMsg(readTslice < head.dimT, @@ -884,10 +955,12 @@ void readGrid4dUni( } if (!fileHandle) { - gzclose(gzf); + return (gzclose(gzf) == Z_OK); } + return 1; #else debMsg("file format not supported without zlib", 1); + return 0; #endif }; void readGrid4dUniCleanup(void **fileHandle) @@ -900,296 +973,61 @@ void readGrid4dUniCleanup(void **fileHandle) } } -template void writeGrid4dRaw(const string &name, Grid4d *grid) +template int writeGrid4dRaw(const string &name, Grid4d *grid) { debMsg("writing grid4d " << grid->getName() << " to raw file " << name, 1); #if NO_ZLIB != 1 gzFile gzf = (gzFile)safeGzopen(name.c_str(), "wb1"); // do some compression - if (!gzf) + if (!gzf) { errMsg("writeGrid4dRaw: can't open file " << name); + return 0; + } gzwrite(gzf, &((*grid)[0]), sizeof(T) * grid->getSizeX() * grid->getSizeY() * grid->getSizeZ() * grid->getSizeT()); - gzclose(gzf); + return (gzclose(gzf) == Z_OK); #else debMsg("file format not supported without zlib", 1); + return 0; #endif } -template void readGrid4dRaw(const string &name, Grid4d *grid) +template int readGrid4dRaw(const string &name, Grid4d *grid) { debMsg("reading grid4d " << grid->getName() << " from raw file " << name, 1); #if NO_ZLIB != 1 gzFile gzf = (gzFile)safeGzopen(name.c_str(), "rb"); - if (!gzf) + if (!gzf) { errMsg("readGrid4dRaw: can't open file " << name); - + return 0; + } IndexInt bytes = sizeof(T) * grid->getSizeX() * grid->getSizeY() * grid->getSizeZ() * grid->getSizeT(); IndexInt readBytes = gzread(gzf, &((*grid)[0]), bytes); assertMsg(bytes == readBytes, "can't read raw file, stream length does not match, " << bytes << " vs " << readBytes); - gzclose(gzf); + return (gzclose(gzf) == Z_OK); #else debMsg("file format not supported without zlib", 1); + return 0; #endif } -//***************************************************************************** -// optional openvdb export - -#if OPENVDB == 1 - -template void writeGridVDB(const string &name, Grid *grid) -{ - debMsg("Writing grid " << grid->getName() << " to vdb file " << name << " not yet supported!", - 1); -} - -template void readGridVDB(const string &name, Grid *grid) -{ - debMsg("Reading grid " << grid->getName() << " from vdb file " << name << " not yet supported!", - 1); -} - -template<> void writeGridVDB(const string &name, Grid *grid) -{ - debMsg("Writing int grid " << grid->getName() << " to vdb file " << name, 1); - - // Create an empty int32-point grid with background value 0. - openvdb::initialize(); - openvdb::Int32Grid::Ptr gridVDB = openvdb::Int32Grid::create(); - gridVDB->setTransform( - openvdb::math::Transform::createLinearTransform(1. / grid->getSizeX())); // voxel size - - // Get an accessor for coordinate-based access to voxels. - openvdb::Int32Grid::Accessor accessor = gridVDB->getAccessor(); - - gridVDB->setGridClass(openvdb::GRID_UNKNOWN); - - // Name the grid "density". - gridVDB->setName(grid->getName()); - - openvdb::io::File file(name); - - FOR_IJK(*grid) - { - openvdb::Coord xyz(i, j, k); - accessor.setValue(xyz, (*grid)(i, j, k)); - } - - // Add the grid pointer to a container. - openvdb::GridPtrVec gridsVDB; - gridsVDB.push_back(gridVDB); - - // Write out the contents of the container. - file.write(gridsVDB); - file.close(); -} - -template<> void readGridVDB(const string &name, Grid *grid) -{ - debMsg("Reading int grid " << grid->getName() << " from vdb file " << name, 1); - - openvdb::initialize(); - openvdb::io::File file(name); - file.open(); - - openvdb::GridBase::Ptr baseGrid; - for (openvdb::io::File::NameIterator nameIter = file.beginName(); nameIter != file.endName(); - ++nameIter) { -# ifndef BLENDER - // Read in only the grid we are interested in. - if (nameIter.gridName() == grid->getName()) { - baseGrid = file.readGrid(nameIter.gridName()); - } - else { - debMsg("skipping grid " << nameIter.gridName(), 1); - } -# else - // For Blender, skip name check and pick first grid from loop - baseGrid = file.readGrid(nameIter.gridName()); - break; -# endif - } - file.close(); - openvdb::Int32Grid::Ptr gridVDB = openvdb::gridPtrCast(baseGrid); - - openvdb::Int32Grid::Accessor accessor = gridVDB->getAccessor(); - - FOR_IJK(*grid) - { - openvdb::Coord xyz(i, j, k); - int v = accessor.getValue(xyz); - (*grid)(i, j, k) = v; - } -} - -template<> void writeGridVDB(const string &name, Grid *grid) -{ - debMsg("Writing real grid " << grid->getName() << " to vdb file " << name, 1); - - // Create an empty floating-point grid with background value 0. - openvdb::initialize(); - openvdb::FloatGrid::Ptr gridVDB = openvdb::FloatGrid::create(); - gridVDB->setTransform( - openvdb::math::Transform::createLinearTransform(1. / grid->getSizeX())); // voxel size - - // Get an accessor for coordinate-based access to voxels. - openvdb::FloatGrid::Accessor accessor = gridVDB->getAccessor(); - - // Identify the grid as a level set. - gridVDB->setGridClass(openvdb::GRID_FOG_VOLUME); - - // Name the grid "density". - gridVDB->setName(grid->getName()); - - openvdb::io::File file(name); - - FOR_IJK(*grid) - { - openvdb::Coord xyz(i, j, k); - accessor.setValue(xyz, (*grid)(i, j, k)); - } - - // Add the grid pointer to a container. - openvdb::GridPtrVec gridsVDB; - gridsVDB.push_back(gridVDB); - - // Write out the contents of the container. - file.write(gridsVDB); - file.close(); -}; - -template<> void readGridVDB(const string &name, Grid *grid) -{ - debMsg("Reading real grid " << grid->getName() << " from vdb file " << name, 1); - - openvdb::initialize(); - openvdb::io::File file(name); - file.open(); - - openvdb::GridBase::Ptr baseGrid; - for (openvdb::io::File::NameIterator nameIter = file.beginName(); nameIter != file.endName(); - ++nameIter) { -# ifndef BLENDER - // Read in only the grid we are interested in. - if (nameIter.gridName() == grid->getName()) { - baseGrid = file.readGrid(nameIter.gridName()); - } - else { - debMsg("skipping grid " << nameIter.gridName(), 1); - } -# else - // For Blender, skip name check and pick first grid from loop - baseGrid = file.readGrid(nameIter.gridName()); - break; -# endif - } - file.close(); - openvdb::FloatGrid::Ptr gridVDB = openvdb::gridPtrCast(baseGrid); - - openvdb::FloatGrid::Accessor accessor = gridVDB->getAccessor(); - - FOR_IJK(*grid) - { - openvdb::Coord xyz(i, j, k); - float v = accessor.getValue(xyz); - (*grid)(i, j, k) = v; - } -}; - -template<> void writeGridVDB(const string &name, Grid *grid) -{ - debMsg("Writing vec3 grid " << grid->getName() << " to vdb file " << name, 1); - - openvdb::initialize(); - openvdb::Vec3SGrid::Ptr gridVDB = openvdb::Vec3SGrid::create(); - // note , warning - velocity content currently not scaled... - gridVDB->setTransform( - openvdb::math::Transform::createLinearTransform(1. / grid->getSizeX())); // voxel size - openvdb::Vec3SGrid::Accessor accessor = gridVDB->getAccessor(); - - // MAC or regular vec grid? - if (grid->getType() & GridBase::TypeMAC) - gridVDB->setGridClass(openvdb::GRID_STAGGERED); - else - gridVDB->setGridClass(openvdb::GRID_UNKNOWN); - - gridVDB->setName(grid->getName()); - - openvdb::io::File file(name); - FOR_IJK(*grid) - { - openvdb::Coord xyz(i, j, k); - Vec3 v = (*grid)(i, j, k); - openvdb::Vec3f vo((float)v[0], (float)v[1], (float)v[2]); - accessor.setValue(xyz, vo); - } - - openvdb::GridPtrVec gridsVDB; - gridsVDB.push_back(gridVDB); - - file.write(gridsVDB); - file.close(); -}; - -template<> void readGridVDB(const string &name, Grid *grid) -{ - debMsg("Reading vec3 grid " << grid->getName() << " from vdb file " << name, 1); - - openvdb::initialize(); - openvdb::io::File file(name); - file.open(); - - openvdb::GridBase::Ptr baseGrid; - for (openvdb::io::File::NameIterator nameIter = file.beginName(); nameIter != file.endName(); - ++nameIter) { -# ifndef BLENDER - // Read in only the grid we are interested in. - if (nameIter.gridName() == grid->getName()) { - baseGrid = file.readGrid(nameIter.gridName()); - } - else { - debMsg("skipping grid " << nameIter.gridName(), 1); - } -# else - // For Blender, skip name check and pick first grid from loop - baseGrid = file.readGrid(nameIter.gridName()); - break; -# endif - } - file.close(); - openvdb::Vec3SGrid::Ptr gridVDB = openvdb::gridPtrCast(baseGrid); - - openvdb::Vec3SGrid::Accessor accessor = gridVDB->getAccessor(); - - FOR_IJK(*grid) - { - openvdb::Coord xyz(i, j, k); - openvdb::Vec3f v = accessor.getValue(xyz); - (*grid)(i, j, k).x = (float)v[0]; - (*grid)(i, j, k).y = (float)v[1]; - (*grid)(i, j, k).z = (float)v[2]; - } -}; - -#endif // OPENVDB==1 - //***************************************************************************** // npz file support (warning - read works, but write generates uncompressed npz; i.e. not // recommended for large volumes) -template void writeGridNumpy(const string &name, Grid *grid) +template int writeGridNumpy(const string &name, Grid *grid) { #if NO_ZLIB == 1 debMsg("file format not supported without zlib", 1); - return; + return 0; #endif #if FLOATINGPOINT_PRECISION != 1 errMsg("writeGridNumpy: Double precision not yet supported"); + return 0; #endif // find suffix to differentiate between npy <-> npz , TODO: check for actual "npy" string @@ -1211,8 +1049,10 @@ template void writeGridNumpy(const string &name, Grid *grid) uDim = 1; else if (grid->getType() & GridBase::TypeVec3 || grid->getType() & GridBase::TypeMAC) uDim = 3; - else + else { errMsg("writeGridNumpy: unknown element type"); + return 0; + } const std::vector shape = {static_cast(grid->getSizeZ()), static_cast(grid->getSizeY()), @@ -1234,16 +1074,18 @@ template void writeGridNumpy(const string &name, Grid *grid) else { cnpy::npy_save(name, &grid[0], shape, "w"); } + return 1; }; -template void readGridNumpy(const string &name, Grid *grid) +template int readGridNumpy(const string &name, Grid *grid) { #if NO_ZLIB == 1 debMsg("file format not supported without zlib", 1); - return; + return 0; #endif #if FLOATINGPOINT_PRECISION != 1 errMsg("readGridNumpy: Double precision not yet supported"); + return 0; #endif // find suffix to differentiate between npy <-> npz @@ -1279,8 +1121,10 @@ template void readGridNumpy(const string &name, Grid *grid) uDim = 1; else if (grid->getType() & GridBase::TypeVec3 || grid->getType() & GridBase::TypeMAC) uDim = 3; - else + else { errMsg("readGridNumpy: unknown element type"); + return 0; + } assertMsg(gridArr.shape[3] == uDim, "grid data dim doesn't match, " << gridArr.shape[3] << " vs " << uDim); @@ -1299,8 +1143,21 @@ template void readGridNumpy(const string &name, Grid *grid) memcpy(&((*grid)[0]), gridArr.data(), sizeof(T) * grid->getSizeX() * grid->getSizeY() * grid->getSizeZ()); + return 1; }; +int writeGridsNumpy(const string &name, std::vector *grids) +{ + errMsg("writeGridsNumpy: writing multiple grids to one .npz file not supported yet"); + return 0; +} + +int readGridsNumpy(const string &name, std::vector *grids) +{ + errMsg("readGridsNumpy: reading multiple grids from one .npz file not supported yet"); + return 0; +} + // adopted from getUniFileSize void getNpzFileSize( const string &name, int &x, int &y, int &z, int *t = NULL, std::string *info = NULL) @@ -1521,77 +1378,63 @@ void PbRegister_quantizeGridVec3() } // explicit instantiation -template void writeGridRaw(const string &name, Grid *grid); -template void writeGridRaw(const string &name, Grid *grid); -template void writeGridRaw(const string &name, Grid *grid); -template void writeGridUni(const string &name, Grid *grid); -template void writeGridUni(const string &name, Grid *grid); -template void writeGridUni(const string &name, Grid *grid); -template void writeGridVol(const string &name, Grid *grid); -template void writeGridVol(const string &name, Grid *grid); -template void writeGridTxt(const string &name, Grid *grid); -template void writeGridTxt(const string &name, Grid *grid); -template void writeGridTxt(const string &name, Grid *grid); - -template void readGridRaw(const string &name, Grid *grid); -template void readGridRaw(const string &name, Grid *grid); -template void readGridRaw(const string &name, Grid *grid); -template void readGridUni(const string &name, Grid *grid); -template void readGridUni(const string &name, Grid *grid); -template void readGridUni(const string &name, Grid *grid); -template void readGridVol(const string &name, Grid *grid); -template void readGridVol(const string &name, Grid *grid); - -template void readGrid4dUni( +template int writeGridRaw(const string &name, Grid *grid); +template int writeGridRaw(const string &name, Grid *grid); +template int writeGridRaw(const string &name, Grid *grid); +template int writeGridUni(const string &name, Grid *grid); +template int writeGridUni(const string &name, Grid *grid); +template int writeGridUni(const string &name, Grid *grid); +template int writeGridVol(const string &name, Grid *grid); +template int writeGridVol(const string &name, Grid *grid); +template int writeGridTxt(const string &name, Grid *grid); +template int writeGridTxt(const string &name, Grid *grid); +template int writeGridTxt(const string &name, Grid *grid); + +template int readGridRaw(const string &name, Grid *grid); +template int readGridRaw(const string &name, Grid *grid); +template int readGridRaw(const string &name, Grid *grid); +template int readGridUni(const string &name, Grid *grid); +template int readGridUni(const string &name, Grid *grid); +template int readGridUni(const string &name, Grid *grid); +template int readGridVol(const string &name, Grid *grid); +template int readGridVol(const string &name, Grid *grid); + +template int readGrid4dUni( const string &name, Grid4d *grid, int readTslice, Grid4d *slice, void **fileHandle); -template void readGrid4dUni(const string &name, - Grid4d *grid, - int readTslice, - Grid4d *slice, - void **fileHandle); -template void readGrid4dUni(const string &name, - Grid4d *grid, - int readTslice, - Grid4d *slice, - void **fileHandle); -template void readGrid4dUni(const string &name, - Grid4d *grid, - int readTslice, - Grid4d *slice, - void **fileHandle); -template void writeGrid4dUni(const string &name, Grid4d *grid); -template void writeGrid4dUni(const string &name, Grid4d *grid); -template void writeGrid4dUni(const string &name, Grid4d *grid); -template void writeGrid4dUni(const string &name, Grid4d *grid); - -template void readGrid4dRaw(const string &name, Grid4d *grid); -template void readGrid4dRaw(const string &name, Grid4d *grid); -template void readGrid4dRaw(const string &name, Grid4d *grid); -template void readGrid4dRaw(const string &name, Grid4d *grid); -template void writeGrid4dRaw(const string &name, Grid4d *grid); -template void writeGrid4dRaw(const string &name, Grid4d *grid); -template void writeGrid4dRaw(const string &name, Grid4d *grid); -template void writeGrid4dRaw(const string &name, Grid4d *grid); - -template void writeGridNumpy(const string &name, Grid *grid); -template void writeGridNumpy(const string &name, Grid *grid); -template void writeGridNumpy(const string &name, Grid *grid); -template void readGridNumpy(const string &name, Grid *grid); -template void readGridNumpy(const string &name, Grid *grid); -template void readGridNumpy(const string &name, Grid *grid); - -#if OPENVDB == 1 -template void writeGridVDB(const string &name, Grid *grid); -template void writeGridVDB(const string &name, Grid *grid); -template void writeGridVDB(const string &name, Grid *grid); - -template void readGridVDB(const string &name, Grid *grid); -template void readGridVDB(const string &name, Grid *grid); -template void readGridVDB(const string &name, Grid *grid); -#endif // OPENVDB==1 +template int readGrid4dUni(const string &name, + Grid4d *grid, + int readTslice, + Grid4d *slice, + void **fileHandle); +template int readGrid4dUni(const string &name, + Grid4d *grid, + int readTslice, + Grid4d *slice, + void **fileHandle); +template int readGrid4dUni(const string &name, + Grid4d *grid, + int readTslice, + Grid4d *slice, + void **fileHandle); +template int writeGrid4dUni(const string &name, Grid4d *grid); +template int writeGrid4dUni(const string &name, Grid4d *grid); +template int writeGrid4dUni(const string &name, Grid4d *grid); +template int writeGrid4dUni(const string &name, Grid4d *grid); + +template int readGrid4dRaw(const string &name, Grid4d *grid); +template int readGrid4dRaw(const string &name, Grid4d *grid); +template int readGrid4dRaw(const string &name, Grid4d *grid); +template int readGrid4dRaw(const string &name, Grid4d *grid); +template int writeGrid4dRaw(const string &name, Grid4d *grid); +template int writeGrid4dRaw(const string &name, Grid4d *grid); +template int writeGrid4dRaw(const string &name, Grid4d *grid); +template int writeGrid4dRaw(const string &name, Grid4d *grid); + +template int writeGridNumpy(const string &name, Grid *grid); +template int writeGridNumpy(const string &name, Grid *grid); +template int writeGridNumpy(const string &name, Grid *grid); +template int readGridNumpy(const string &name, Grid *grid); +template int readGridNumpy(const string &name, Grid *grid); +template int readGridNumpy(const string &name, Grid *grid); } // namespace Manta - -namespace Manta { - -} diff --git a/extern/mantaflow/preprocessed/fileio/iomeshes.cpp b/extern/mantaflow/preprocessed/fileio/iomeshes.cpp index 906b849fffb..1c50376de77 100644 --- a/extern/mantaflow/preprocessed/fileio/iomeshes.cpp +++ b/extern/mantaflow/preprocessed/fileio/iomeshes.cpp @@ -146,21 +146,25 @@ void mdataReadConvert(gzFile &gzf, MeshDataImpl &mdata, void *ptr, i // mesh data //***************************************************************************** -void readBobjFile(const string &name, Mesh *mesh, bool append) +int readBobjFile(const string &name, Mesh *mesh, bool append) { debMsg("reading mesh file " << name, 1); if (!append) mesh->clear(); - else + else { errMsg("readBobj: append not yet implemented!"); + return 0; + } #if NO_ZLIB != 1 const Real dx = mesh->getParent()->getDx(); const Vec3 gs = toVec3(mesh->getParent()->getGridSize()); gzFile gzf = (gzFile)safeGzopen(name.c_str(), "rb1"); // do some compression - if (!gzf) + if (!gzf) { errMsg("readBobj: unable to open file"); + return 0; + } // read vertices int num = 0; @@ -198,15 +202,16 @@ void readBobjFile(const string &name, Mesh *mesh, bool append) } } // note - vortex sheet info ignored for now... (see writeBobj) - gzclose(gzf); debMsg("read mesh , triangles " << mesh->numTris() << ", vertices " << mesh->numNodes() << " ", 1); + return (gzclose(gzf) == Z_OK); #else debMsg("file format not supported without zlib", 1); + return 0; #endif } -void writeBobjFile(const string &name, Mesh *mesh) +int writeBobjFile(const string &name, Mesh *mesh) { debMsg("writing mesh file " << name, 1); #if NO_ZLIB != 1 @@ -214,8 +219,10 @@ void writeBobjFile(const string &name, Mesh *mesh) const Vec3i gs = mesh->getParent()->getGridSize(); gzFile gzf = (gzFile)safeGzopen(name.c_str(), "wb1"); // do some compression - if (!gzf) + if (!gzf) { errMsg("writeBobj: unable to open file"); + return 0; + } // write vertices int numVerts = mesh->numNodes(); @@ -292,18 +299,21 @@ void writeBobjFile(const string &name, Mesh *mesh) } } - gzclose(gzf); + return (gzclose(gzf) == Z_OK); #else debMsg("file format not supported without zlib", 1); + return 0; #endif } -void readObjFile(const std::string &name, Mesh *mesh, bool append) +int readObjFile(const std::string &name, Mesh *mesh, bool append) { ifstream ifs(name.c_str()); - if (!ifs.good()) + if (!ifs.good()) { errMsg("can't open file '" + name + "'"); + return 0; + } if (!append) mesh->clear(); @@ -323,8 +333,10 @@ void readObjFile(const std::string &name, Mesh *mesh, bool append) } else if (id == "vn") { // normals - if (!mesh->numNodes()) + if (!mesh->numNodes()) { errMsg("invalid amount of nodes"); + return 0; + } Node n = mesh->nodes(cnt); ifs >> n.normal.x >> n.normal.y >> n.normal.z; cnt++; @@ -349,8 +361,10 @@ void readObjFile(const std::string &name, Mesh *mesh, bool append) if (face.find('/') != string::npos) face = face.substr(0, face.find('/')); // ignore other indices int idx = atoi(face.c_str()) - 1; - if (idx < 0) + if (idx < 0) { errMsg("invalid face encountered"); + return 0; + } idx += nodebase; t.c[i] = idx; } @@ -363,17 +377,20 @@ void readObjFile(const std::string &name, Mesh *mesh, bool append) getline(ifs, id); } ifs.close(); + return 1; } // write regular .obj file, in line with bobj.gz output (but only verts & tris for now) -void writeObjFile(const string &name, Mesh *mesh) +int writeObjFile(const string &name, Mesh *mesh) { const Real dx = mesh->getParent()->getDx(); const Vec3i gs = mesh->getParent()->getGridSize(); ofstream ofs(name.c_str()); - if (!ofs.good()) + if (!ofs.good()) { errMsg("writeObjFile: can't open file " << name); + return 0; + } ofs << "o MantaMesh\n"; @@ -405,16 +422,19 @@ void writeObjFile(const string &name, Mesh *mesh) } ofs.close(); + return 1; } -template void readMdataUni(const std::string &name, MeshDataImpl *mdata) +template int readMdataUni(const std::string &name, MeshDataImpl *mdata) { debMsg("reading mesh data " << mdata->getName() << " from uni file " << name, 1); #if NO_ZLIB != 1 gzFile gzf = (gzFile)safeGzopen(name.c_str(), "rb"); - if (!gzf) + if (!gzf) { errMsg("can't open file " << name); + return 0; + } char ID[5] = {0, 0, 0, 0, 0}; gzread(gzf, ID, 4); @@ -440,13 +460,14 @@ template void readMdataUni(const std::string &name, MeshDataImpl *md << readBytes); # endif } - gzclose(gzf); + return (gzclose(gzf) == Z_OK); #else debMsg("file format not supported without zlib", 1); + return 0; #endif } -template void writeMdataUni(const std::string &name, MeshDataImpl *mdata) +template int writeMdataUni(const std::string &name, MeshDataImpl *mdata) { debMsg("writing mesh data " << mdata->getName() << " to uni file " << name, 1); @@ -461,8 +482,10 @@ template void writeMdataUni(const std::string &name, MeshDataImpl *m head.timestamp = stamp.time; gzFile gzf = (gzFile)safeGzopen(name.c_str(), "wb1"); // do some compression - if (!gzf) + if (!gzf) { errMsg("can't open file " << name); + return 0; + } gzwrite(gzf, ID, 4); # if FLOATINGPOINT_PRECISION != 1 @@ -474,19 +497,20 @@ template void writeMdataUni(const std::string &name, MeshDataImpl *m gzwrite(gzf, &head, sizeof(UniMeshHeader)); gzwrite(gzf, &(mdata->get(0)), sizeof(T) * head.dim); # endif - gzclose(gzf); + return (gzclose(gzf) == Z_OK); #else debMsg("file format not supported without zlib", 1); + return 0; #endif }; // explicit instantiation -template void writeMdataUni(const std::string &name, MeshDataImpl *mdata); -template void writeMdataUni(const std::string &name, MeshDataImpl *mdata); -template void writeMdataUni(const std::string &name, MeshDataImpl *mdata); -template void readMdataUni(const std::string &name, MeshDataImpl *mdata); -template void readMdataUni(const std::string &name, MeshDataImpl *mdata); -template void readMdataUni(const std::string &name, MeshDataImpl *mdata); +template int writeMdataUni(const std::string &name, MeshDataImpl *mdata); +template int writeMdataUni(const std::string &name, MeshDataImpl *mdata); +template int writeMdataUni(const std::string &name, MeshDataImpl *mdata); +template int readMdataUni(const std::string &name, MeshDataImpl *mdata); +template int readMdataUni(const std::string &name, MeshDataImpl *mdata); +template int readMdataUni(const std::string &name, MeshDataImpl *mdata); } // namespace Manta diff --git a/extern/mantaflow/preprocessed/fileio/ioparticles.cpp b/extern/mantaflow/preprocessed/fileio/ioparticles.cpp index 2eab485beb3..84283a25b07 100644 --- a/extern/mantaflow/preprocessed/fileio/ioparticles.cpp +++ b/extern/mantaflow/preprocessed/fileio/ioparticles.cpp @@ -158,7 +158,7 @@ void pdataReadConvert(gzFile &gzf, static const int PartSysSize = sizeof(Vector3D) + sizeof(int); -void writeParticlesUni(const std::string &name, const BasicParticleSystem *parts) +int writeParticlesUni(const std::string &name, const BasicParticleSystem *parts) { debMsg("writing particles " << parts->getName() << " to uni file " << name, 1); @@ -177,8 +177,10 @@ void writeParticlesUni(const std::string &name, const BasicParticleSystem *parts head.timestamp = stamp.time; gzFile gzf = (gzFile)safeGzopen(name.c_str(), "wb1"); // do some compression - if (!gzf) + if (!gzf) { errMsg("can't open file " << name); + return 0; + } gzwrite(gzf, ID, 4); # if FLOATINGPOINT_PRECISION != 1 @@ -195,26 +197,30 @@ void writeParticlesUni(const std::string &name, const BasicParticleSystem *parts gzwrite(gzf, &head, sizeof(UniPartHeader)); gzwrite(gzf, &((*parts)[0]), PartSysSize * head.dim); # endif - gzclose(gzf); + return (gzclose(gzf) == Z_OK); #else debMsg("file format not supported without zlib", 1); + return 0; #endif }; -void readParticlesUni(const std::string &name, BasicParticleSystem *parts) +int readParticlesUni(const std::string &name, BasicParticleSystem *parts) { debMsg("reading particles " << parts->getName() << " from uni file " << name, 1); #if NO_ZLIB != 1 gzFile gzf = (gzFile)safeGzopen(name.c_str(), "rb"); - if (!gzf) + if (!gzf) { errMsg("can't open file " << name); + return 0; + } char ID[5] = {0, 0, 0, 0, 0}; gzread(gzf, ID, 4); if (!strcmp(ID, "PB01")) { errMsg("particle uni file format v01 not supported anymore"); + return 0; } else if (!strcmp(ID, "PB02")) { // current file format @@ -249,13 +255,14 @@ void readParticlesUni(const std::string &name, BasicParticleSystem *parts) parts->transformPositions(Vec3i(head.dimX, head.dimY, head.dimZ), parts->getParent()->getGridSize()); } - gzclose(gzf); + return (gzclose(gzf) == Z_OK); #else debMsg("file format not supported without zlib", 1); + return 0; #endif }; -template void writePdataUni(const std::string &name, ParticleDataImpl *pdata) +template int writePdataUni(const std::string &name, ParticleDataImpl *pdata) { debMsg("writing particle data " << pdata->getName() << " to uni file " << name, 1); @@ -274,8 +281,10 @@ template void writePdataUni(const std::string &name, ParticleDataImpl void writePdataUni(const std::string &name, ParticleDataImplget(0)), sizeof(T) * head.dim); # endif - gzclose(gzf); + return (gzclose(gzf) == Z_OK); #else debMsg("file format not supported without zlib", 1); + return 0; #endif }; -template void readPdataUni(const std::string &name, ParticleDataImpl *pdata) +template int readPdataUni(const std::string &name, ParticleDataImpl *pdata) { debMsg("reading particle data " << pdata->getName() << " from uni file " << name, 1); #if NO_ZLIB != 1 gzFile gzf = (gzFile)safeGzopen(name.c_str(), "rb"); - if (!gzf) + if (!gzf) { errMsg("can't open file " << name); + return 0; + } char ID[5] = {0, 0, 0, 0, 0}; gzread(gzf, ID, 4); @@ -327,18 +339,19 @@ template void readPdataUni(const std::string &name, ParticleDataImpl << readBytes); # endif } - gzclose(gzf); + return (gzclose(gzf) == Z_OK); #else debMsg("file format not supported without zlib", 1); + return 0; #endif } // explicit instantiation -template void writePdataUni(const std::string &name, ParticleDataImpl *pdata); -template void writePdataUni(const std::string &name, ParticleDataImpl *pdata); -template void writePdataUni(const std::string &name, ParticleDataImpl *pdata); -template void readPdataUni(const std::string &name, ParticleDataImpl *pdata); -template void readPdataUni(const std::string &name, ParticleDataImpl *pdata); -template void readPdataUni(const std::string &name, ParticleDataImpl *pdata); +template int writePdataUni(const std::string &name, ParticleDataImpl *pdata); +template int writePdataUni(const std::string &name, ParticleDataImpl *pdata); +template int writePdataUni(const std::string &name, ParticleDataImpl *pdata); +template int readPdataUni(const std::string &name, ParticleDataImpl *pdata); +template int readPdataUni(const std::string &name, ParticleDataImpl *pdata); +template int readPdataUni(const std::string &name, ParticleDataImpl *pdata); } // namespace Manta diff --git a/extern/mantaflow/preprocessed/fileio/ioutil.cpp b/extern/mantaflow/preprocessed/fileio/ioutil.cpp index e04633c5634..cc63cf87ac1 100644 --- a/extern/mantaflow/preprocessed/fileio/ioutil.cpp +++ b/extern/mantaflow/preprocessed/fileio/ioutil.cpp @@ -18,6 +18,10 @@ #include "mantaio.h" +#if OPENVDB == 1 +# include "openvdb/openvdb.h" +#endif + #if NO_ZLIB != 1 extern "C" { # include @@ -40,7 +44,7 @@ static wstring stringToWstring(const char *str) MultiByteToWideChar(CP_UTF8, 0, str, strlen(str), &strWide[0], length_wc); return strWide; } -# endif +# endif // WIN32==1 void *safeGzopen(const char *filename, const char *mode) { @@ -55,6 +59,54 @@ void *safeGzopen(const char *filename, const char *mode) return gzfile; } -#endif +#endif // NO_ZLIB != 1 + +#if defined(OPENVDB) +// Convert from OpenVDB value to Manta value. +template void convertFrom(S &in, T *out) +{ + errMsg("OpenVDB convertFrom Warning: Unsupported type conversion"); +} + +template<> void convertFrom(int &in, int *out) +{ + (*out) = in; +} + +template<> void convertFrom(float &in, Real *out) +{ + (*out) = (Real)in; +} + +template<> void convertFrom(openvdb::Vec3s &in, Vec3 *out) +{ + (*out).x = in.x(); + (*out).y = in.y(); + (*out).z = in.z(); +} + +// Convert to OpenVDB value from Manta value. +template void convertTo(S *out, T &in) +{ + errMsg("OpenVDB convertTo Warning: Unsupported type conversion"); +} + +template<> void convertTo(int *out, int &in) +{ + (*out) = in; +} + +template<> void convertTo(float *out, Real &in) +{ + (*out) = (float)in; +} + +template<> void convertTo(openvdb::Vec3s *out, Vec3 &in) +{ + (*out).x() = in.x; + (*out).y() = in.y; + (*out).z() = in.z; +} +#endif // OPENVDB==1 } // namespace diff --git a/extern/mantaflow/preprocessed/fileio/iovdb.cpp b/extern/mantaflow/preprocessed/fileio/iovdb.cpp new file mode 100644 index 00000000000..31958dcb977 --- /dev/null +++ b/extern/mantaflow/preprocessed/fileio/iovdb.cpp @@ -0,0 +1,618 @@ + + +// DO NOT EDIT ! +// This file is generated using the MantaFlow preprocessor (prep generate). + +/****************************************************************************** + * + * MantaFlow fluid solver framework + * Copyright 2020 Sebastian Barschkis, Nils Thuerey + * + * This program is free software, distributed under the terms of the + * Apache License, Version 2.0 + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Loading and writing grids and particles from and to OpenVDB files. + * + ******************************************************************************/ + +#include +#include +#include +#include + +#include "mantaio.h" +#include "grid.h" +#include "vector4d.h" +#include "grid4d.h" +#include "particle.h" + +#if OPENVDB == 1 +# include "openvdb/openvdb.h" +# include +# include +#endif + +#define POSITION_NAME "P" +#define FLAG_NAME "U" + +using namespace std; + +namespace Manta { + +#if OPENVDB == 1 + +template void importVDB(typename GridType::Ptr from, Grid *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); + } +} + +template +void importVDB(VDBType vdbValue, ParticleDataImpl *to, int index, float voxelSize) +{ + (void)voxelSize; // Unused + T toMantaValue; + convertFrom(vdbValue, &toMantaValue); + to->set(index, toMantaValue); +} + +void importVDB(openvdb::points::PointDataGrid::Ptr from, + BasicParticleSystem *to, + std::vector &toPData, + float voxelSize) +{ + openvdb::Index64 count = openvdb::points::pointCount(from->tree()); + to->resizeAll(count); + + int cnt = 0; + for (auto leafIter = from->tree().cbeginLeaf(); leafIter; ++leafIter) { + const openvdb::points::AttributeArray &positionArray = leafIter->constAttributeArray( + POSITION_NAME); + const openvdb::points::AttributeArray &flagArray = leafIter->constAttributeArray(FLAG_NAME); + + openvdb::points::AttributeHandle positionHandle(positionArray); + openvdb::points::AttributeHandle flagHandle(flagArray); + + // Get vdb handles to pdata objects in pdata list + std::vector>> pDataHandlesInt; + std::vector>> pDataHandlesReal; + std::vector>> + pDataHandlesVec3; + + int pDataIndex = 0; + for (ParticleDataBase *pdb : toPData) { + std::string name = pdb->getName(); + const openvdb::points::AttributeArray &pDataArray = leafIter->constAttributeArray(name); + + if (pdb->getType() == ParticleDataBase::TypeInt) { + openvdb::points::AttributeHandle intHandle(pDataArray); + std::tuple> tuple = std::make_tuple(pDataIndex, + intHandle); + pDataHandlesInt.push_back(tuple); + } + else if (pdb->getType() == ParticleDataBase::TypeReal) { + openvdb::points::AttributeHandle floatHandle(pDataArray); + std::tuple> tuple = std::make_tuple( + pDataIndex, floatHandle); + pDataHandlesReal.push_back(tuple); + } + else if (pdb->getType() == ParticleDataBase::TypeVec3) { + openvdb::points::AttributeHandle vec3Handle(pDataArray); + std::tuple> tuple = std::make_tuple( + pDataIndex, vec3Handle); + pDataHandlesVec3.push_back(tuple); + } + else { + errMsg("importVDB: unknown ParticleDataBase type"); + } + ++pDataIndex; + } + + for (auto indexIter = leafIter->beginIndexOn(); indexIter; ++indexIter) { + // Extract the voxel-space position of the point (always between (-0.5, -0.5, -0.5) and (0.5, + // 0.5, 0.5)). + openvdb::Vec3s voxelPosition = positionHandle.get(*indexIter); + const openvdb::Vec3d xyz = indexIter.getCoord().asVec3d(); + // Compute the world-space position of the point. + openvdb::Vec3f worldPosition = from->transform().indexToWorld(voxelPosition + xyz); + int flag = flagHandle.get(*indexIter); + + Vec3 toMantaValue; + convertFrom(worldPosition, &toMantaValue); + (*to)[cnt].pos = toMantaValue; + (*to)[cnt].pos /= voxelSize; // convert from world space to grid space + (*to)[cnt].flag = flag; + + for (std::tuple> tuple : pDataHandlesInt) { + int pDataIndex = std::get<0>(tuple); + int vdbValue = std::get<1>(tuple).get(*indexIter); + + ParticleDataImpl *pdi = dynamic_cast *>(toPData[pDataIndex]); + importVDB(vdbValue, pdi, cnt, voxelSize); + } + for (std::tuple> tuple : pDataHandlesReal) { + int pDataIndex = std::get<0>(tuple); + float vdbValue = std::get<1>(tuple).get(*indexIter); + + ParticleDataImpl *pdi = dynamic_cast *>(toPData[pDataIndex]); + importVDB(vdbValue, pdi, cnt, voxelSize); + } + for (std::tuple> tuple : + pDataHandlesVec3) { + int pDataIndex = std::get<0>(tuple); + openvdb::Vec3f voxelPosition = std::get<1>(tuple).get(*indexIter); + + ParticleDataImpl *pdi = dynamic_cast *>(toPData[pDataIndex]); + importVDB(voxelPosition, pdi, cnt, voxelSize); + } + ++cnt; + } + } +} + +template +static void setGridOptions(typename GridType::Ptr grid, + string name, + openvdb::GridClass cls, + float voxelSize, + bool precisionHalf) +{ + grid->setTransform(openvdb::math::Transform::createLinearTransform(voxelSize)); + grid->setGridClass(cls); + grid->setName(name); + grid->setSaveFloatAsHalf(precisionHalf); +} + +template typename GridType::Ptr exportVDB(Grid *from) +{ + 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); + } + return to; +} + +template +void exportVDB(ParticleDataImpl *from, + openvdb::points::PointDataGrid::Ptr to, + openvdb::tools::PointIndexGrid::Ptr pIndex, + bool skipDeletedParts) +{ + std::vector vdbValues; + std::string name = from->getName(); + + FOR_PARTS(*from) + { + // Optionally, skip exporting particles that have been marked as deleted + BasicParticleSystem *pp = dynamic_cast(from->getParticleSys()); + if (skipDeletedParts && !pp->isActive(idx)) { + continue; + } + MantaType fromMantaValue = (*from)[idx]; + VDBType vdbValue; + convertTo(&vdbValue, fromMantaValue); + vdbValues.push_back(vdbValue); + } + + openvdb::NamePair attribute = + openvdb::points::TypedAttributeArray::attributeType(); + openvdb::points::appendAttribute(to->tree(), name, attribute); + + // Create a wrapper around the vdb values vector. + const openvdb::points::PointAttributeVector wrapper(vdbValues); + + // Populate the attribute on the points + openvdb::points::populateAttribute>( + to->tree(), pIndex->tree(), name, wrapper); +} + +openvdb::points::PointDataGrid::Ptr exportVDB(BasicParticleSystem *from, + std::vector &fromPData, + bool skipDeletedParts, + float voxelSize) +{ + std::vector positions; + std::vector flags; + + FOR_PARTS(*from) + { + // Optionally, skip exporting particles that have been marked as deleted + if (skipDeletedParts && !from->isActive(idx)) { + continue; + } + Vector3D pos = toVec3f((*from)[idx].pos); + pos *= voxelSize; // convert from grid space to world space + openvdb::Vec3s posVDB(pos.x, pos.y, pos.z); + positions.push_back(posVDB); + + int flag = (*from)[idx].flag; + flags.push_back(flag); + } + + const openvdb::points::PointAttributeVector positionsWrapper(positions); + openvdb::math::Transform::Ptr transform = openvdb::math::Transform::createLinearTransform( + voxelSize); + + openvdb::tools::PointIndexGrid::Ptr pointIndexGrid = + openvdb::tools::createPointIndexGrid(positionsWrapper, + *transform); + + // TODO (sebbas): Use custom codec for attributes? + // using Codec = openvdb::points::FixedPointCodec; + openvdb::points::PointDataGrid::Ptr to = + openvdb::points::createPointDataGrid( + *pointIndexGrid, positionsWrapper, *transform); + + openvdb::NamePair flagAttribute = + openvdb::points::TypedAttributeArray::attributeType(); + openvdb::points::appendAttribute(to->tree(), FLAG_NAME, flagAttribute); + // Create a wrapper around the flag vector. + openvdb::points::PointAttributeVector flagWrapper(flags); + // Populate the "flag" attribute on the points + openvdb::points::populateAttribute>( + to->tree(), pointIndexGrid->tree(), FLAG_NAME, flagWrapper); + + // Add all already buffered pdata to this particle grid + for (ParticleDataBase *pdb : fromPData) { + if (pdb->getType() == ParticleDataBase::TypeInt) { + debMsg("Writing int particle data '" << pdb->getName() << "'", 1); + ParticleDataImpl *pdi = dynamic_cast *>(pdb); + exportVDB(pdi, to, pointIndexGrid, skipDeletedParts); + } + else if (pdb->getType() == ParticleDataBase::TypeReal) { + debMsg("Writing real particle data '" << pdb->getName() << "'", 1); + ParticleDataImpl *pdi = dynamic_cast *>(pdb); + exportVDB(pdi, to, pointIndexGrid, skipDeletedParts); + } + else if (pdb->getType() == ParticleDataBase::TypeVec3) { + debMsg("Writing Vec3 particle data '" << pdb->getName() << "'", 1); + ParticleDataImpl *pdi = dynamic_cast *>(pdb); + exportVDB(pdi, to, pointIndexGrid, skipDeletedParts); + } + else { + errMsg("exportVDB: unknown ParticleDataBase type"); + } + } + return to; +} + +static void registerCustomCodecs() +{ + using Codec = openvdb::points::FixedPointCodec; + openvdb::points::TypedAttributeArray::registerType(); +} + +int writeObjectsVDB(const string &filename, + std::vector *objects, + float worldSize, + bool skipDeletedParts, + int compression, + bool precisionHalf) +{ + openvdb::initialize(); + openvdb::io::File file(filename); + openvdb::GridPtrVec gridsVDB; + + // TODO (sebbas): Use custom codec for flag attribute? + // Register codecs one, this makes sure custom attributes can be read + // registerCustomCodecs(); + + std::vector pdbBuffer; + + for (std::vector::iterator iter = objects->begin(); iter != objects->end(); ++iter) { + openvdb::GridClass gClass = openvdb::GRID_UNKNOWN; + openvdb::GridBase::Ptr vdbGrid; + + PbClass *object = dynamic_cast(*iter); + const Real dx = object->getParent()->getDx(); + const Real voxelSize = worldSize * dx; + const string objectName = object->getName(); + + if (GridBase *mantaGrid = dynamic_cast(*iter)) { + + if (mantaGrid->getType() & GridBase::TypeInt) { + debMsg("Writing int grid '" << mantaGrid->getName() << "' to vdb file " << filename, 1); + Grid *mantaIntGrid = (Grid *)mantaGrid; + vdbGrid = exportVDB(mantaIntGrid); + gridsVDB.push_back(vdbGrid); + } + else if (mantaGrid->getType() & GridBase::TypeReal) { + debMsg("Writing real grid '" << mantaGrid->getName() << "' to vdb file " << filename, 1); + gClass = (mantaGrid->getType() & GridBase::TypeLevelset) ? openvdb::GRID_LEVEL_SET : + openvdb::GRID_FOG_VOLUME; + Grid *mantaRealGrid = (Grid *)mantaGrid; + vdbGrid = exportVDB(mantaRealGrid); + gridsVDB.push_back(vdbGrid); + } + else if (mantaGrid->getType() & GridBase::TypeVec3) { + debMsg("Writing vec3 grid '" << mantaGrid->getName() << "' to vdb file " << filename, 1); + gClass = (mantaGrid->getType() & GridBase::TypeMAC) ? openvdb::GRID_STAGGERED : + openvdb::GRID_UNKNOWN; + Grid *mantaVec3Grid = (Grid *)mantaGrid; + vdbGrid = exportVDB(mantaVec3Grid); + gridsVDB.push_back(vdbGrid); + } + else { + errMsg("writeObjectsVDB: unknown grid type"); + return 0; + } + } + else if (BasicParticleSystem *mantaPP = dynamic_cast(*iter)) { + debMsg("Writing particle system '" << mantaPP->getName() + << "' (and buffered pData) to vdb file " << filename, + 1); + vdbGrid = exportVDB(mantaPP, pdbBuffer, skipDeletedParts, voxelSize); + gridsVDB.push_back(vdbGrid); + pdbBuffer.clear(); + } + // Particle data will only be saved if there is a particle system too. + else if (ParticleDataBase *mantaPPImpl = dynamic_cast(*iter)) { + debMsg("Buffering particle data '" << mantaPPImpl->getName() << "' to vdb file " << filename, + 1); + pdbBuffer.push_back(mantaPPImpl); + } + else { + errMsg("writeObjectsVDB: Unsupported Python object. Cannot write to .vdb file " << filename); + return 0; + } + + // Set additional grid attributes, e.g. name, grid class, compression level, etc. + if (vdbGrid) { + setGridOptions(vdbGrid, objectName, gClass, voxelSize, precisionHalf); + } + } + + // Give out a warning if pData items were present but could not be saved due to missing particle + // system. + if (!pdbBuffer.empty()) { + for (ParticleDataBase *pdb : pdbBuffer) { + debMsg("writeObjectsVDB Warning: Particle data '" + << pdb->getName() + << "' has not been saved. It's parent particle system was needs to be given too.", + 1); + } + } + + // Write only if the is at least one grid, optionally write with compression. + if (gridsVDB.size()) { + int vdb_flags = openvdb::io::COMPRESS_ACTIVE_MASK; + switch (compression) { + case COMPRESSION_NONE: { + vdb_flags = openvdb::io::COMPRESS_NONE; + break; + } + case COMPRESSION_ZIP: { + vdb_flags |= openvdb::io::COMPRESS_ZIP; + break; + } + case COMPRESSION_BLOSC: { +# if OPENVDB_BLOSC == 1 + vdb_flags |= openvdb::io::COMPRESS_BLOSC; +# else + debMsg("OpenVDB was built without Blosc support, using Zip compression instead", 1); + vdb_flags |= openvdb::io::COMPRESS_ZIP; +# endif // OPENVDB_BLOSC==1 + break; + } + } + file.setCompression(vdb_flags); + file.write(gridsVDB); + } + file.close(); + return 1; +} + +int readObjectsVDB(const string &filename, std::vector *objects, float worldSize) +{ + + openvdb::initialize(); + openvdb::io::File file(filename); + openvdb::GridPtrVec gridsVDB; + + // TODO (sebbas): Use custom codec for flag attribute? + // Register codecs one, this makes sure custom attributes can be read + // registerCustomCodecs(); + + try { + file.setCopyMaxBytes(0); + file.open(); + gridsVDB = *(file.getGrids()); + openvdb::MetaMap::Ptr metadata = file.getMetadata(); + (void)metadata; // Unused for now + } + catch (const openvdb::IoError &e) { + debMsg("readObjectsVDB: Could not open vdb file " << filename, 1); + file.close(); + return 0; + } + file.close(); + + // A buffer to store a handle to pData objects. These will be read alongside a particle system. + std::vector pdbBuffer; + + for (std::vector::iterator iter = objects->begin(); iter != objects->end(); ++iter) { + + if (gridsVDB.empty()) { + debMsg("readObjectsVDB: No vdb grids in file " << filename, 1); + } + // If there is just one grid in this file, load it regardless of name match (to vdb caches per + // grid). + bool onlyGrid = (gridsVDB.size() == 1); + + PbClass *object = dynamic_cast(*iter); + const Real dx = object->getParent()->getDx(); + const Real voxelSize = worldSize * dx; + + // Particle data objects are treated separately - buffered and inserted when reading the + // particle system + if (ParticleDataBase *mantaPPImpl = dynamic_cast(*iter)) { + debMsg("Buffering particle data '" << mantaPPImpl->getName() << "' from vdb file " + << filename, + 1); + pdbBuffer.push_back(mantaPPImpl); + continue; + } + + // For every manta object, we loop through the vdb grid list and check for a match + for (const openvdb::GridBase::Ptr vdbGrid : gridsVDB) { + bool nameMatch = (vdbGrid->getName() == (*iter)->getName()); + + // Sanity checks: Only load valid grids and make sure names match. + if (!vdbGrid) { + debMsg("Skipping invalid vdb grid '" << vdbGrid->getName() << "' in file " << filename, 1); + continue; + } + if (!nameMatch && !onlyGrid) { + continue; + } + if (GridBase *mantaGrid = dynamic_cast(*iter)) { + + if (mantaGrid->getType() & GridBase::TypeInt) { + debMsg("Reading into grid '" << mantaGrid->getName() << "' from int grid '" + << vdbGrid->getName() << "' in vdb file " << filename, + 1); + openvdb::Int32Grid::Ptr vdbIntGrid = openvdb::gridPtrCast(vdbGrid); + Grid *mantaIntGrid = (Grid *)mantaGrid; + importVDB(vdbIntGrid, mantaIntGrid); + } + else if (mantaGrid->getType() & GridBase::TypeReal) { + debMsg("Reading into grid '" << mantaGrid->getName() << "' from real grid '" + << vdbGrid->getName() << "' in vdb file " << filename, + 1); + openvdb::FloatGrid::Ptr vdbFloatGrid = openvdb::gridPtrCast(vdbGrid); + Grid *mantaRealGrid = (Grid *)mantaGrid; + importVDB(vdbFloatGrid, mantaRealGrid); + } + else if (mantaGrid->getType() & GridBase::TypeVec3) { + debMsg("Reading into grid '" << mantaGrid->getName() << "' from vec3 grid '" + << vdbGrid->getName() << "' in vdb file " << filename, + 1); + openvdb::Vec3SGrid::Ptr vdbVec3Grid = openvdb::gridPtrCast(vdbGrid); + Grid *mantaVec3Grid = (Grid *)mantaGrid; + importVDB(vdbVec3Grid, mantaVec3Grid); + } + else { + errMsg("readObjectsVDB: unknown grid type"); + return 0; + } + } + else if (BasicParticleSystem *mantaPP = dynamic_cast(*iter)) { + debMsg("Reading into particle system '" << mantaPP->getName() << "' from particle system '" + << vdbGrid->getName() << "' in vdb file " + << filename, + 1); + openvdb::points::PointDataGrid::Ptr vdbPointGrid = + openvdb::gridPtrCast(vdbGrid); + importVDB(vdbPointGrid, mantaPP, pdbBuffer, voxelSize); + pdbBuffer.clear(); + } + else { + errMsg("readObjectsVDB: Unsupported Python object. Cannot read from .vdb file " + << filename); + return 0; + } + } + } + + // Give out a warning if pData items were present but could not be read due to missing particle + // system. + if (!pdbBuffer.empty()) { + for (ParticleDataBase *pdb : pdbBuffer) { + debMsg("readObjectsVDB Warning: Particle data '" + << pdb->getName() + << "' has not been read. The parent particle system needs to be given too.", + 1); + } + } + + return 1; +} + +template void importVDB(int vdbValue, + ParticleDataImpl *to, + int index, + float voxelSize = 1.0); +template void importVDB(float vdbValue, + ParticleDataImpl *to, + int index, + float voxelSize = 1.0); +template void importVDB(openvdb::Vec3s vdbValue, + ParticleDataImpl *to, + int index, + float voxelSize = 1.0); + +void importVDB(openvdb::points::PointDataGrid::Ptr from, + BasicParticleSystem *to, + std::vector &toPData, + float voxelSize = 1.0); +template void importVDB(openvdb::Int32Grid::Ptr from, Grid *to); +template void importVDB(openvdb::FloatGrid::Ptr from, Grid *to); +template void importVDB(openvdb::Vec3SGrid::Ptr from, Grid *to); + +template openvdb::Int32Grid::Ptr exportVDB(Grid *from); +template openvdb::FloatGrid::Ptr exportVDB(Grid *from); +template openvdb::Vec3SGrid::Ptr exportVDB(Grid *from); + +openvdb::points::PointDataGrid::Ptr exportVDB(BasicParticleSystem *from, + std::vector &fromPData, + bool skipDeletedParts = false, + float voxelSize = 1.0); +template void exportVDB(ParticleDataImpl *from, + openvdb::points::PointDataGrid::Ptr to, + openvdb::tools::PointIndexGrid::Ptr pIndex, + bool skipDeletedParts = false); +template void exportVDB(ParticleDataImpl *from, + openvdb::points::PointDataGrid::Ptr to, + openvdb::tools::PointIndexGrid::Ptr pIndex, + bool skipDeletedParts = false); +template void exportVDB(ParticleDataImpl *from, + openvdb::points::PointDataGrid::Ptr to, + openvdb::tools::PointIndexGrid::Ptr pIndex, + bool skipDeletedParts = false); + +#else + +int writeObjectsVDB(const string &filename, + std::vector *objects, + float worldSize, + bool skipDeletedParts, + int compression, + bool precisionHalf) +{ + errMsg("Cannot save to .vdb file. Mantaflow has not been built with OpenVDB support."); + return 0; +} + +int readObjectsVDB(const string &filename, std::vector *objects, float worldSize) +{ + errMsg("Cannot load from .vdb file. Mantaflow has not been built with OpenVDB support."); + return 0; +} + +#endif // OPENVDB==1 + +} // namespace Manta diff --git a/extern/mantaflow/preprocessed/fileio/mantaio.cpp b/extern/mantaflow/preprocessed/fileio/mantaio.cpp new file mode 100644 index 00000000000..fd2b36bf7cb --- /dev/null +++ b/extern/mantaflow/preprocessed/fileio/mantaio.cpp @@ -0,0 +1,144 @@ + + +// DO NOT EDIT ! +// This file is generated using the MantaFlow preprocessor (prep generate). + +/****************************************************************************** + * + * MantaFlow fluid solver framework + * Copyright 2020 Sebastian Barschkis, Nils Thuerey + * + * This program is free software, distributed under the terms of the + * Apache License, Version 2.0 + * http://www.apache.org/licenses/LICENSE-2.0 + * + * General functions that make use of functions from other io files. + * + ******************************************************************************/ + +#include "mantaio.h" + +using namespace std; + +namespace Manta { + +int load(const string &name, std::vector &objects, float worldSize = 1.0) +{ + if (name.find_last_of('.') == string::npos) + errMsg("file '" + name + "' does not have an extension"); + string ext = name.substr(name.find_last_of('.')); + + if (ext == ".raw") + return readGridsRaw(name, &objects); + else if (ext == ".uni") + return readGridsUni(name, &objects); + else if (ext == ".vol") + return readGridsVol(name, &objects); + if (ext == ".vdb") + return readObjectsVDB(name, &objects, worldSize); + else if (ext == ".npz") + return readGridsNumpy(name, &objects); + else if (ext == ".txt") + return readGridsTxt(name, &objects); + else + errMsg("file '" + name + "' filetype not supported"); + return 0; +} +static PyObject *_W_0(PyObject *_self, PyObject *_linargs, PyObject *_kwds) +{ + try { + PbArgs _args(_linargs, _kwds); + FluidSolver *parent = _args.obtainParent(); + bool noTiming = _args.getOpt("notiming", -1, 0); + pbPreparePlugin(parent, "load", !noTiming); + PyObject *_retval = 0; + { + ArgLocker _lock; + const string &name = _args.get("name", 0, &_lock); + std::vector &objects = *_args.getPtr>( + "objects", 1, &_lock); + float worldSize = _args.getOpt("worldSize", 2, 1.0, &_lock); + _retval = toPy(load(name, objects, worldSize)); + _args.check(); + } + pbFinalizePlugin(parent, "load", !noTiming); + return _retval; + } + catch (std::exception &e) { + pbSetError("load", e.what()); + return 0; + } +} +static const Pb::Register _RP_load("", "load", _W_0); +extern "C" { +void PbRegister_load() +{ + KEEP_UNUSED(_RP_load); +} +} + +int save(const string &name, + std::vector &objects, + float worldSize = 1.0, + bool skipDeletedParts = false, + int compression = COMPRESSION_ZIP, + bool precisionHalf = true) +{ + if (name.find_last_of('.') == string::npos) + errMsg("file '" + name + "' does not have an extension"); + string ext = name.substr(name.find_last_of('.')); + + if (ext == ".raw") + return writeGridsRaw(name, &objects); + else if (ext == ".uni") + return writeGridsUni(name, &objects); + else if (ext == ".vol") + return writeGridsVol(name, &objects); + if (ext == ".vdb") + return writeObjectsVDB( + name, &objects, worldSize, skipDeletedParts, compression, precisionHalf); + else if (ext == ".npz") + return writeGridsNumpy(name, &objects); + else if (ext == ".txt") + return writeGridsTxt(name, &objects); + else + errMsg("file '" + name + "' filetype not supported"); + return 0; +} +static PyObject *_W_1(PyObject *_self, PyObject *_linargs, PyObject *_kwds) +{ + try { + PbArgs _args(_linargs, _kwds); + FluidSolver *parent = _args.obtainParent(); + bool noTiming = _args.getOpt("notiming", -1, 0); + pbPreparePlugin(parent, "save", !noTiming); + PyObject *_retval = 0; + { + ArgLocker _lock; + const string &name = _args.get("name", 0, &_lock); + std::vector &objects = *_args.getPtr>( + "objects", 1, &_lock); + float worldSize = _args.getOpt("worldSize", 2, 1.0, &_lock); + bool skipDeletedParts = _args.getOpt("skipDeletedParts", 3, false, &_lock); + int compression = _args.getOpt("compression", 4, COMPRESSION_ZIP, &_lock); + bool precisionHalf = _args.getOpt("precisionHalf", 5, true, &_lock); + _retval = toPy(save(name, objects, worldSize, skipDeletedParts, compression, precisionHalf)); + _args.check(); + } + pbFinalizePlugin(parent, "save", !noTiming); + return _retval; + } + catch (std::exception &e) { + pbSetError("save", e.what()); + return 0; + } +} +static const Pb::Register _RP_save("", "save", _W_1); +extern "C" { +void PbRegister_save() +{ + KEEP_UNUSED(_RP_save); +} +} + +} // namespace Manta diff --git a/extern/mantaflow/preprocessed/fileio/mantaio.h b/extern/mantaflow/preprocessed/fileio/mantaio.h index fbfe4bdd5d4..8b543ad4f93 100644 --- a/extern/mantaflow/preprocessed/fileio/mantaio.h +++ b/extern/mantaflow/preprocessed/fileio/mantaio.h @@ -21,62 +21,98 @@ #include +#include "manta.h" + +// OpenVDB compression flags +#define COMPRESSION_NONE 0 +#define COMPRESSION_ZIP 1 +#define COMPRESSION_BLOSC 2 + namespace Manta { -// forward decl. +// Forward declations class Mesh; class FlagGrid; +class GridBase; template class Grid; template class Grid4d; class BasicParticleSystem; template class ParticleDataImpl; template class MeshDataImpl; -void writeObjFile(const std::string &name, Mesh *mesh); -void writeBobjFile(const std::string &name, Mesh *mesh); -void readObjFile(const std::string &name, Mesh *mesh, bool append); -void readBobjFile(const std::string &name, Mesh *mesh, bool append); - -template void writeGridRaw(const std::string &name, Grid *grid); -template void writeGridUni(const std::string &name, Grid *grid); -template void writeGridVol(const std::string &name, Grid *grid); -template void writeGridTxt(const std::string &name, Grid *grid); - -#if OPENVDB == 1 -template void writeGridVDB(const std::string &name, Grid *grid); -template void readGridVDB(const std::string &name, Grid *grid); -#endif // OPENVDB==1 -template void writeGridNumpy(const std::string &name, Grid *grid); -template void readGridNumpy(const std::string &name, Grid *grid); - -template void readGridUni(const std::string &name, Grid *grid); -template void readGridRaw(const std::string &name, Grid *grid); -template void readGridVol(const std::string &name, Grid *grid); - -template void writeGrid4dUni(const std::string &name, Grid4d *grid); +// Obj format +int writeObjFile(const std::string &name, Mesh *mesh); +int writeBobjFile(const std::string &name, Mesh *mesh); +int readObjFile(const std::string &name, Mesh *mesh, bool append); +int readBobjFile(const std::string &name, Mesh *mesh, bool append); + +// Other formats (Raw, Uni, Vol) +template int readGridUni(const std::string &name, Grid *grid); +template int readGridRaw(const std::string &name, Grid *grid); +template int readGridVol(const std::string &name, Grid *grid); +int readGridsRaw(const std::string &name, std::vector *grids); +int readGridsUni(const std::string &name, std::vector *grids); +int readGridsVol(const std::string &name, std::vector *grids); +int readGridsTxt(const std::string &name, std::vector *grids); + +template int writeGridRaw(const std::string &name, Grid *grid); +template int writeGridUni(const std::string &name, Grid *grid); +template int writeGridVol(const std::string &name, Grid *grid); +template int writeGridTxt(const std::string &name, Grid *grid); +int writeGridsRaw(const std::string &name, std::vector *grids); +int writeGridsUni(const std::string &name, std::vector *grids); +int writeGridsVol(const std::string &name, std::vector *grids); +int writeGridsTxt(const std::string &name, std::vector *grids); + +// OpenVDB +int writeObjectsVDB(const std::string &filename, + std::vector *objects, + float scale = 1.0, + bool skipDeletedParts = false, + int compression = COMPRESSION_ZIP, + bool precisionHalf = true); +int readObjectsVDB(const std::string &filename, + std::vector *objects, + float scale = 1.0); + +// Numpy +template int writeGridNumpy(const std::string &name, Grid *grid); +template int readGridNumpy(const std::string &name, Grid *grid); + +int writeGridsNumpy(const std::string &name, std::vector *grids); +int readGridsNumpy(const std::string &name, std::vector *grids); + +// 4D Grids +template int writeGrid4dUni(const std::string &name, Grid4d *grid); template -void readGrid4dUni(const std::string &name, - Grid4d *grid, - int readTslice = -1, - Grid4d *slice = NULL, - void **fileHandle = NULL); +int readGrid4dUni(const std::string &name, + Grid4d *grid, + int readTslice = -1, + Grid4d *slice = NULL, + void **fileHandle = NULL); void readGrid4dUniCleanup(void **fileHandle); -template void writeGrid4dRaw(const std::string &name, Grid4d *grid); -template void readGrid4dRaw(const std::string &name, Grid4d *grid); +template int writeGrid4dRaw(const std::string &name, Grid4d *grid); +template int readGrid4dRaw(const std::string &name, Grid4d *grid); -void writeParticlesUni(const std::string &name, const BasicParticleSystem *parts); -void readParticlesUni(const std::string &name, BasicParticleSystem *parts); +// Particles + particle data +int writeParticlesUni(const std::string &name, const BasicParticleSystem *parts); +int readParticlesUni(const std::string &name, BasicParticleSystem *parts); -template void writePdataUni(const std::string &name, ParticleDataImpl *pdata); -template void readPdataUni(const std::string &name, ParticleDataImpl *pdata); +template int writePdataUni(const std::string &name, ParticleDataImpl *pdata); +template int readPdataUni(const std::string &name, ParticleDataImpl *pdata); -template void writeMdataUni(const std::string &name, MeshDataImpl *mdata); -template void readMdataUni(const std::string &name, MeshDataImpl *mdata); +// Mesh data +template int writeMdataUni(const std::string &name, MeshDataImpl *mdata); +template int readMdataUni(const std::string &name, MeshDataImpl *mdata); +// Helpers void getUniFileSize( const std::string &name, int &x, int &y, int &z, int *t = NULL, std::string *info = NULL); - void *safeGzopen(const char *filename, const char *mode); +#if OPENVDB == 1 +template void convertFrom(S &in, T *out); +template void convertTo(S *out, T &in); +#endif } // namespace Manta -- cgit v1.2.3