diff options
Diffstat (limited to 'extern')
19 files changed, 1388 insertions, 514 deletions
diff --git a/extern/mantaflow/CMakeLists.txt b/extern/mantaflow/CMakeLists.txt index bdee06349d2..8b7453bf4c5 100644 --- a/extern/mantaflow/CMakeLists.txt +++ b/extern/mantaflow/CMakeLists.txt @@ -54,6 +54,10 @@ if(WITH_OPENVDB) add_definitions(-DOPENVDB_STATICLIB) endif() +if(WITH_OPENVDB_BLOSC) + add_definitions(-DOPENVDB_BLOSC=1) +endif() + if(WIN32) add_definitions(-D_USE_MATH_DEFINES) endif() @@ -106,10 +110,12 @@ set(SRC ${MANTA_PP}/fastmarch.cpp ${MANTA_PP}/fastmarch.h ${MANTA_PP}/fastmarch.h.reg.cpp - ${MANTA_PP}/fileio/ioutil.cpp ${MANTA_PP}/fileio/iogrids.cpp ${MANTA_PP}/fileio/iomeshes.cpp ${MANTA_PP}/fileio/ioparticles.cpp + ${MANTA_PP}/fileio/ioutil.cpp + ${MANTA_PP}/fileio/iovdb.cpp + ${MANTA_PP}/fileio/mantaio.cpp ${MANTA_PP}/fileio/mantaio.h ${MANTA_PP}/fileio/mantaio.h.reg.cpp ${MANTA_PP}/fluidsolver.cpp diff --git a/extern/mantaflow/helper/pwrapper/pconvert.cpp b/extern/mantaflow/helper/pwrapper/pconvert.cpp index 9ada75519fc..861a2c070bd 100644 --- a/extern/mantaflow/helper/pwrapper/pconvert.cpp +++ b/extern/mantaflow/helper/pwrapper/pconvert.cpp @@ -96,6 +96,37 @@ template<> PyObject *toPy<PbClass *>(const PbClass_Ptr &obj) { return obj->getPyObject(); } +template<> PyObject *toPy<std::vector<PbClass *>>(const std::vector<PbClass *> &vec) +{ + PyObject *listObj = PyList_New(vec.size()); + if (!listObj) + throw logic_error("Unable to allocate memory for Python list"); + for (unsigned int i = 0; i < vec.size(); i++) { + PbClass *pb = vec[i]; + PyObject *item = pb->getPyObject(); + if (!item) { + Py_DECREF(listObj); + throw logic_error("Unable to allocate memory for Python list"); + } + PyList_SET_ITEM(listObj, i, item); + } + return listObj; +} +template<> PyObject *toPy<std::vector<float>>(const std::vector<float> &vec) +{ + PyObject *listObj = PyList_New(vec.size()); + if (!listObj) + throw logic_error("Unable to allocate memory for Python list"); + for (unsigned int i = 0; i < vec.size(); i++) { + PyObject *item = toPy<float>(vec[i]); + if (!item) { + Py_DECREF(listObj); + throw logic_error("Unable to allocate memory for Python list"); + } + PyList_SET_ITEM(listObj, i, item); + } + return listObj; +} template<> float fromPy<float>(PyObject *obj) { @@ -125,6 +156,42 @@ template<> PyObject *fromPy<PyObject *>(PyObject *obj) { return obj; } +template<> PbClass *fromPy<PbClass *>(PyObject *obj) +{ + PbClass *pbo = Pb::objFromPy(obj); + + if (!PyType_Check(obj)) + return pbo; + + const char *tname = ((PyTypeObject *)obj)->tp_name; + pbo->setName(tname); + + return pbo; +} +template<> std::vector<PbClass *> fromPy<std::vector<PbClass *>>(PyObject *obj) +{ + std::vector<PbClass *> vec; + if (PyList_Check(obj)) { + int sz = PyList_Size(obj); + for (int i = 0; i < sz; ++i) { + PyObject *lobj = PyList_GetItem(obj, i); + vec.push_back(fromPy<PbClass *>(lobj)); + } + } + return vec; +} +template<> std::vector<float> fromPy<std::vector<float>>(PyObject *obj) +{ + std::vector<float> vec; + if (PyList_Check(obj)) { + int sz = PyList_Size(obj); + for (int i = 0; i < sz; ++i) { + PyObject *lobj = PyList_GetItem(obj, i); + vec.push_back(fromPy<float>(lobj)); + } + } + return vec; +} template<> int fromPy<int>(PyObject *obj) { #if PY_MAJOR_VERSION <= 2 @@ -259,11 +326,10 @@ template<class T> T *tmpAlloc(PyObject *obj, std::vector<void *> *tmp) { if (!tmp) throw Error("dynamic de-ref not supported for this type"); - void *ptr = malloc(sizeof(T)); - tmp->push_back(ptr); - *((T *)ptr) = fromPy<T>(obj); - return (T *)ptr; + T *ptr = new T(fromPy<T>(obj)); + tmp->push_back(ptr); + return ptr; } template<> float *fromPyPtr<float>(PyObject *obj, std::vector<void *> *tmp) { @@ -301,6 +367,11 @@ template<> Vec4i *fromPyPtr<Vec4i>(PyObject *obj, std::vector<void *> *tmp) { return tmpAlloc<Vec4i>(obj, tmp); } +template<> +std::vector<PbClass *> *fromPyPtr<std::vector<PbClass *>>(PyObject *obj, std::vector<void *> *tmp) +{ + return tmpAlloc<std::vector<PbClass *>>(obj, tmp); +} template<> bool isPy<float>(PyObject *obj) { @@ -404,6 +475,18 @@ template<> bool isPy<PbType>(PyObject *obj) { return PyType_Check(obj); } +template<> bool isPy<std::vector<PbClass *>>(PyObject *obj) +{ + if (PyList_Check(obj)) + return true; + return false; +} +template<> bool isPy<std::vector<float>>(PyObject *obj) +{ + if (PyList_Check(obj)) + return true; + return false; +} //****************************************************************************** // PbArgs class defs @@ -417,7 +500,7 @@ PbArgs::PbArgs(PyObject *linarg, PyObject *dict) : mLinArgs(0), mKwds(0) PbArgs::~PbArgs() { for (int i = 0; i < (int)mTmpStorage.size(); i++) - free(mTmpStorage[i]); + operator delete(mTmpStorage[i]); mTmpStorage.clear(); } diff --git a/extern/mantaflow/helper/pwrapper/pconvert.h b/extern/mantaflow/helper/pwrapper/pconvert.h index 9c72b8b57b9..87f4248f6f1 100644 --- a/extern/mantaflow/helper/pwrapper/pconvert.h +++ b/extern/mantaflow/helper/pwrapper/pconvert.h @@ -57,6 +57,10 @@ template<> Vec3 *fromPyPtr<Vec3>(PyObject *obj, std::vector<void *> *tmp); template<> Vec3i *fromPyPtr<Vec3i>(PyObject *obj, std::vector<void *> *tmp); template<> Vec4 *fromPyPtr<Vec4>(PyObject *obj, std::vector<void *> *tmp); template<> Vec4i *fromPyPtr<Vec4i>(PyObject *obj, std::vector<void *> *tmp); +template<> +std::vector<PbClass *> *fromPyPtr<std::vector<PbClass *>>(PyObject *obj, std::vector<void *> *tmp); +template<> +std::vector<float> *fromPyPtr<std::vector<float>>(PyObject *obj, std::vector<void *> *tmp); PyObject *incref(PyObject *obj); template<class T> PyObject *toPy(const T &v) @@ -99,6 +103,9 @@ template<> Vec4 fromPy<Vec4>(PyObject *obj); template<> Vec4i fromPy<Vec4i>(PyObject *obj); template<> PbType fromPy<PbType>(PyObject *obj); template<> PbTypeVec fromPy<PbTypeVec>(PyObject *obj); +template<> PbClass *fromPy<PbClass *>(PyObject *obj); +template<> std::vector<PbClass *> fromPy<std::vector<PbClass *>>(PyObject *obj); +template<> std::vector<float> fromPy<std::vector<float>>(PyObject *obj); template<> PyObject *toPy<int>(const int &v); template<> PyObject *toPy<std::string>(const std::string &val); @@ -111,6 +118,8 @@ template<> PyObject *toPy<Vec4i>(const Vec4i &v); template<> PyObject *toPy<Vec4>(const Vec4 &v); typedef PbClass *PbClass_Ptr; template<> PyObject *toPy<PbClass *>(const PbClass_Ptr &obj); +template<> PyObject *toPy<std::vector<PbClass *>>(const std::vector<PbClass *> &vec); +template<> PyObject *toPy<std::vector<float>>(const std::vector<float> &vec); template<> bool isPy<float>(PyObject *obj); template<> bool isPy<double>(PyObject *obj); @@ -124,6 +133,8 @@ template<> bool isPy<Vec3i>(PyObject *obj); template<> bool isPy<Vec4>(PyObject *obj); template<> bool isPy<Vec4i>(PyObject *obj); template<> bool isPy<PbType>(PyObject *obj); +template<> bool isPy<std::vector<PbClass *>>(PyObject *obj); +template<> bool isPy<std::vector<float>>(PyObject *obj); //! Encapsulation of python arguments class PbArgs { 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<class T> void writeGridTxt(const string &name, Grid<T> *grid) +template<class T> int writeGridTxt(const string &name, Grid<T> *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<PbClass *> *grids) +{ + errMsg("writeGridsTxt: writing multiple grids to one .txt file not supported yet"); + return 0; } -template<class T> void writeGridRaw(const string &name, Grid<T> *grid) +int readGridsTxt(const string &name, std::vector<PbClass *> *grids) +{ + errMsg("readGridsTxt: writing multiple grids from one .txt file not supported yet"); + return 0; +} + +template<class T> int writeGridRaw(const string &name, Grid<T> *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<class T> void readGridRaw(const string &name, Grid<T> *grid) +template<class T> int readGridRaw(const string &name, Grid<T> *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<PbClass *> *grids) +{ + errMsg("writeGridsRaw: writing multiple grids to one .raw file not supported yet"); + return 0; +} + +int readGridsRaw(const string &name, std::vector<PbClass *> *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<class T> void writeGridUni(const string &name, Grid<T> *grid) +template<class T> int writeGridUni(const string &name, Grid<T> *grid) { debMsg("Writing grid " << grid->getName() << " to uni file " << name, 1); @@ -496,12 +525,16 @@ template<class T> void writeGridUni(const string &name, Grid<T> *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<class T> void writeGridUni(const string &name, Grid<T> *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<class T> void readGridUni(const string &name, Grid<T> *grid) +template<class T> int readGridUni(const string &name, Grid<T> *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<class T> void readGridUni(const string &name, Grid<T> *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<class T> void writeGridVol(const string &name, Grid<T> *grid) +int writeGridsUni(const string &name, std::vector<PbClass *> *grids) +{ + errMsg("writeGridsUni: writing multiple grids to one .uni file not supported yet"); + return 0; +} + +int readGridsUni(const string &name, std::vector<PbClass *> *grids) +{ + errMsg("readGridsUni: reading multiple grids from one .uni file not supported yet"); + return 0; +} + +template<class T> int writeGridVol(const string &name, Grid<T> *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<PbClass *> *grids) +{ + errMsg("writeGridsVol: writing multiple grids to one .vol file not supported yet"); + return 0; +} + +int readGridsVol(const string &name, std::vector<PbClass *> *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<Real>(const string &name, Grid<Real> *grid) +template<> int writeGridVol<Real>(const string &name, Grid<Real> *grid) { debMsg("writing real grid " << grid->getName() << " to vol file " << name, 1); @@ -651,7 +714,7 @@ template<> void writeGridVol<Real>(const string &name, Grid<Real> *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<Real>(const string &name, Grid<Real> *grid) fwrite(&value, sizeof(float), 1, fp); } #endif - - fclose(fp); + return (!fclose(fp)); }; -template<class T> void readGridVol(const string &name, Grid<T> *grid) +template<class T> int readGridVol(const string &name, Grid<T> *grid) { debMsg("writing grid " << grid->getName() << " to vol file " << name, 1); errMsg("readGridVol: Type not yet supported!"); + return 0; } -template<> void readGridVol<Real>(const string &name, Grid<Real> *grid) +template<> int readGridVol<Real>(const string &name, Grid<Real> *grid) { debMsg("reading real grid " << grid->getName() << " from vol file " << name, 1); @@ -685,7 +748,7 @@ template<> void readGridVol<Real>(const string &name, Grid<Real> *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<Real>(const string &name, Grid<Real> *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<class T> void writeGrid4dUni(const string &name, Grid4d<T> *grid) +template<class T> int writeGrid4dUni(const string &name, Grid4d<T> *grid) { debMsg("writing grid4d " << grid->getName() << " to uni file " << name, 1); @@ -733,12 +796,16 @@ template<class T> void writeGrid4dUni(const string &name, Grid4d<T> *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<class T> void writeGrid4dUni(const string &name, Grid4d<T> *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<class T> -void readGrid4dUni( +int readGrid4dUni( const string &name, Grid4d<T> *grid, int readTslice, Grid4d<T> *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<class T> void writeGrid4dRaw(const string &name, Grid4d<T> *grid) +template<class T> int writeGrid4dRaw(const string &name, Grid4d<T> *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<class T> void readGrid4dRaw(const string &name, Grid4d<T> *grid) +template<class T> int readGrid4dRaw(const string &name, Grid4d<T> *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<class T> void writeGridVDB(const string &name, Grid<T> *grid) -{ - debMsg("Writing grid " << grid->getName() << " to vdb file " << name << " not yet supported!", - 1); -} - -template<class T> void readGridVDB(const string &name, Grid<T> *grid) -{ - debMsg("Reading grid " << grid->getName() << " from vdb file " << name << " not yet supported!", - 1); -} - -template<> void writeGridVDB(const string &name, Grid<int> *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<int> *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<openvdb::Int32Grid>(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<Real> *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<Real> *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<openvdb::FloatGrid>(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<Vec3> *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<Vec3> *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<openvdb::Vec3SGrid>(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<class T> void writeGridNumpy(const string &name, Grid<T> *grid) +template<class T> int writeGridNumpy(const string &name, Grid<T> *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<class T> void writeGridNumpy(const string &name, Grid<T> *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<size_t> shape = {static_cast<size_t>(grid->getSizeZ()), static_cast<size_t>(grid->getSizeY()), @@ -1234,16 +1074,18 @@ template<class T> void writeGridNumpy(const string &name, Grid<T> *grid) else { cnpy::npy_save(name, &grid[0], shape, "w"); } + return 1; }; -template<class T> void readGridNumpy(const string &name, Grid<T> *grid) +template<class T> int readGridNumpy(const string &name, Grid<T> *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<class T> void readGridNumpy(const string &name, Grid<T> *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<class T> void readGridNumpy(const string &name, Grid<T> *grid) memcpy(&((*grid)[0]), gridArr.data<T>(), sizeof(T) * grid->getSizeX() * grid->getSizeY() * grid->getSizeZ()); + return 1; }; +int writeGridsNumpy(const string &name, std::vector<PbClass *> *grids) +{ + errMsg("writeGridsNumpy: writing multiple grids to one .npz file not supported yet"); + return 0; +} + +int readGridsNumpy(const string &name, std::vector<PbClass *> *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<int>(const string &name, Grid<int> *grid); -template void writeGridRaw<Real>(const string &name, Grid<Real> *grid); -template void writeGridRaw<Vec3>(const string &name, Grid<Vec3> *grid); -template void writeGridUni<int>(const string &name, Grid<int> *grid); -template void writeGridUni<Real>(const string &name, Grid<Real> *grid); -template void writeGridUni<Vec3>(const string &name, Grid<Vec3> *grid); -template void writeGridVol<int>(const string &name, Grid<int> *grid); -template void writeGridVol<Vec3>(const string &name, Grid<Vec3> *grid); -template void writeGridTxt<int>(const string &name, Grid<int> *grid); -template void writeGridTxt<Real>(const string &name, Grid<Real> *grid); -template void writeGridTxt<Vec3>(const string &name, Grid<Vec3> *grid); - -template void readGridRaw<int>(const string &name, Grid<int> *grid); -template void readGridRaw<Real>(const string &name, Grid<Real> *grid); -template void readGridRaw<Vec3>(const string &name, Grid<Vec3> *grid); -template void readGridUni<int>(const string &name, Grid<int> *grid); -template void readGridUni<Real>(const string &name, Grid<Real> *grid); -template void readGridUni<Vec3>(const string &name, Grid<Vec3> *grid); -template void readGridVol<int>(const string &name, Grid<int> *grid); -template void readGridVol<Vec3>(const string &name, Grid<Vec3> *grid); - -template void readGrid4dUni<int>( +template int writeGridRaw<int>(const string &name, Grid<int> *grid); +template int writeGridRaw<Real>(const string &name, Grid<Real> *grid); +template int writeGridRaw<Vec3>(const string &name, Grid<Vec3> *grid); +template int writeGridUni<int>(const string &name, Grid<int> *grid); +template int writeGridUni<Real>(const string &name, Grid<Real> *grid); +template int writeGridUni<Vec3>(const string &name, Grid<Vec3> *grid); +template int writeGridVol<int>(const string &name, Grid<int> *grid); +template int writeGridVol<Vec3>(const string &name, Grid<Vec3> *grid); +template int writeGridTxt<int>(const string &name, Grid<int> *grid); +template int writeGridTxt<Real>(const string &name, Grid<Real> *grid); +template int writeGridTxt<Vec3>(const string &name, Grid<Vec3> *grid); + +template int readGridRaw<int>(const string &name, Grid<int> *grid); +template int readGridRaw<Real>(const string &name, Grid<Real> *grid); +template int readGridRaw<Vec3>(const string &name, Grid<Vec3> *grid); +template int readGridUni<int>(const string &name, Grid<int> *grid); +template int readGridUni<Real>(const string &name, Grid<Real> *grid); +template int readGridUni<Vec3>(const string &name, Grid<Vec3> *grid); +template int readGridVol<int>(const string &name, Grid<int> *grid); +template int readGridVol<Vec3>(const string &name, Grid<Vec3> *grid); + +template int readGrid4dUni<int>( const string &name, Grid4d<int> *grid, int readTslice, Grid4d<int> *slice, void **fileHandle); -template void readGrid4dUni<Real>(const string &name, - Grid4d<Real> *grid, - int readTslice, - Grid4d<Real> *slice, - void **fileHandle); -template void readGrid4dUni<Vec3>(const string &name, - Grid4d<Vec3> *grid, - int readTslice, - Grid4d<Vec3> *slice, - void **fileHandle); -template void readGrid4dUni<Vec4>(const string &name, - Grid4d<Vec4> *grid, - int readTslice, - Grid4d<Vec4> *slice, - void **fileHandle); -template void writeGrid4dUni<int>(const string &name, Grid4d<int> *grid); -template void writeGrid4dUni<Real>(const string &name, Grid4d<Real> *grid); -template void writeGrid4dUni<Vec3>(const string &name, Grid4d<Vec3> *grid); -template void writeGrid4dUni<Vec4>(const string &name, Grid4d<Vec4> *grid); - -template void readGrid4dRaw<int>(const string &name, Grid4d<int> *grid); -template void readGrid4dRaw<Real>(const string &name, Grid4d<Real> *grid); -template void readGrid4dRaw<Vec3>(const string &name, Grid4d<Vec3> *grid); -template void readGrid4dRaw<Vec4>(const string &name, Grid4d<Vec4> *grid); -template void writeGrid4dRaw<int>(const string &name, Grid4d<int> *grid); -template void writeGrid4dRaw<Real>(const string &name, Grid4d<Real> *grid); -template void writeGrid4dRaw<Vec3>(const string &name, Grid4d<Vec3> *grid); -template void writeGrid4dRaw<Vec4>(const string &name, Grid4d<Vec4> *grid); - -template void writeGridNumpy<int>(const string &name, Grid<int> *grid); -template void writeGridNumpy<Real>(const string &name, Grid<Real> *grid); -template void writeGridNumpy<Vec3>(const string &name, Grid<Vec3> *grid); -template void readGridNumpy<int>(const string &name, Grid<int> *grid); -template void readGridNumpy<Real>(const string &name, Grid<Real> *grid); -template void readGridNumpy<Vec3>(const string &name, Grid<Vec3> *grid); - -#if OPENVDB == 1 -template void writeGridVDB<int>(const string &name, Grid<int> *grid); -template void writeGridVDB<Vec3>(const string &name, Grid<Vec3> *grid); -template void writeGridVDB<Real>(const string &name, Grid<Real> *grid); - -template void readGridVDB<int>(const string &name, Grid<int> *grid); -template void readGridVDB<Vec3>(const string &name, Grid<Vec3> *grid); -template void readGridVDB<Real>(const string &name, Grid<Real> *grid); -#endif // OPENVDB==1 +template int readGrid4dUni<Real>(const string &name, + Grid4d<Real> *grid, + int readTslice, + Grid4d<Real> *slice, + void **fileHandle); +template int readGrid4dUni<Vec3>(const string &name, + Grid4d<Vec3> *grid, + int readTslice, + Grid4d<Vec3> *slice, + void **fileHandle); +template int readGrid4dUni<Vec4>(const string &name, + Grid4d<Vec4> *grid, + int readTslice, + Grid4d<Vec4> *slice, + void **fileHandle); +template int writeGrid4dUni<int>(const string &name, Grid4d<int> *grid); +template int writeGrid4dUni<Real>(const string &name, Grid4d<Real> *grid); +template int writeGrid4dUni<Vec3>(const string &name, Grid4d<Vec3> *grid); +template int writeGrid4dUni<Vec4>(const string &name, Grid4d<Vec4> *grid); + +template int readGrid4dRaw<int>(const string &name, Grid4d<int> *grid); +template int readGrid4dRaw<Real>(const string &name, Grid4d<Real> *grid); +template int readGrid4dRaw<Vec3>(const string &name, Grid4d<Vec3> *grid); +template int readGrid4dRaw<Vec4>(const string &name, Grid4d<Vec4> *grid); +template int writeGrid4dRaw<int>(const string &name, Grid4d<int> *grid); +template int writeGrid4dRaw<Real>(const string &name, Grid4d<Real> *grid); +template int writeGrid4dRaw<Vec3>(const string &name, Grid4d<Vec3> *grid); +template int writeGrid4dRaw<Vec4>(const string &name, Grid4d<Vec4> *grid); + +template int writeGridNumpy<int>(const string &name, Grid<int> *grid); +template int writeGridNumpy<Real>(const string &name, Grid<Real> *grid); +template int writeGridNumpy<Vec3>(const string &name, Grid<Vec3> *grid); +template int readGridNumpy<int>(const string &name, Grid<int> *grid); +template int readGridNumpy<Real>(const string &name, Grid<Real> *grid); +template int readGridNumpy<Vec3>(const string &name, Grid<Vec3> *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<Vec3>(gzFile &gzf, MeshDataImpl<Vec3> &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<class T> void readMdataUni(const std::string &name, MeshDataImpl<T> *mdata) +template<class T> int readMdataUni(const std::string &name, MeshDataImpl<T> *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<class T> void readMdataUni(const std::string &name, MeshDataImpl<T> *md << readBytes); # endif } - gzclose(gzf); + return (gzclose(gzf) == Z_OK); #else debMsg("file format not supported without zlib", 1); + return 0; #endif } -template<class T> void writeMdataUni(const std::string &name, MeshDataImpl<T> *mdata) +template<class T> int writeMdataUni(const std::string &name, MeshDataImpl<T> *mdata) { debMsg("writing mesh data " << mdata->getName() << " to uni file " << name, 1); @@ -461,8 +482,10 @@ template<class T> void writeMdataUni(const std::string &name, MeshDataImpl<T> *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<class T> void writeMdataUni(const std::string &name, MeshDataImpl<T> *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<int>(const std::string &name, MeshDataImpl<int> *mdata); -template void writeMdataUni<Real>(const std::string &name, MeshDataImpl<Real> *mdata); -template void writeMdataUni<Vec3>(const std::string &name, MeshDataImpl<Vec3> *mdata); -template void readMdataUni<int>(const std::string &name, MeshDataImpl<int> *mdata); -template void readMdataUni<Real>(const std::string &name, MeshDataImpl<Real> *mdata); -template void readMdataUni<Vec3>(const std::string &name, MeshDataImpl<Vec3> *mdata); +template int writeMdataUni<int>(const std::string &name, MeshDataImpl<int> *mdata); +template int writeMdataUni<Real>(const std::string &name, MeshDataImpl<Real> *mdata); +template int writeMdataUni<Vec3>(const std::string &name, MeshDataImpl<Vec3> *mdata); +template int readMdataUni<int>(const std::string &name, MeshDataImpl<int> *mdata); +template int readMdataUni<Real>(const std::string &name, MeshDataImpl<Real> *mdata); +template int readMdataUni<Vec3>(const std::string &name, MeshDataImpl<Vec3> *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<Vec3>(gzFile &gzf, static const int PartSysSize = sizeof(Vector3D<float>) + 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<class T> void writePdataUni(const std::string &name, ParticleDataImpl<T> *pdata) +template<class T> int writePdataUni(const std::string &name, ParticleDataImpl<T> *pdata) { debMsg("writing particle data " << pdata->getName() << " to uni file " << name, 1); @@ -274,8 +281,10 @@ template<class T> void writePdataUni(const std::string &name, ParticleDataImpl<T 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 @@ -287,21 +296,24 @@ template<class T> void writePdataUni(const std::string &name, ParticleDataImpl<T gzwrite(gzf, &head, sizeof(UniPartHeader)); gzwrite(gzf, &(pdata->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 }; -template<class T> void readPdataUni(const std::string &name, ParticleDataImpl<T> *pdata) +template<class T> int readPdataUni(const std::string &name, ParticleDataImpl<T> *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<class T> void readPdataUni(const std::string &name, ParticleDataImpl<T> << 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<int>(const std::string &name, ParticleDataImpl<int> *pdata); -template void writePdataUni<Real>(const std::string &name, ParticleDataImpl<Real> *pdata); -template void writePdataUni<Vec3>(const std::string &name, ParticleDataImpl<Vec3> *pdata); -template void readPdataUni<int>(const std::string &name, ParticleDataImpl<int> *pdata); -template void readPdataUni<Real>(const std::string &name, ParticleDataImpl<Real> *pdata); -template void readPdataUni<Vec3>(const std::string &name, ParticleDataImpl<Vec3> *pdata); +template int writePdataUni<int>(const std::string &name, ParticleDataImpl<int> *pdata); +template int writePdataUni<Real>(const std::string &name, ParticleDataImpl<Real> *pdata); +template int writePdataUni<Vec3>(const std::string &name, ParticleDataImpl<Vec3> *pdata); +template int readPdataUni<int>(const std::string &name, ParticleDataImpl<int> *pdata); +template int readPdataUni<Real>(const std::string &name, ParticleDataImpl<Real> *pdata); +template int readPdataUni<Vec3>(const std::string &name, ParticleDataImpl<Vec3> *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 <zlib.h> @@ -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<class S, class T> 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<class S, class T> 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 <iostream> +#include <fstream> +#include <cstdlib> +#include <cstring> + +#include "mantaio.h" +#include "grid.h" +#include "vector4d.h" +#include "grid4d.h" +#include "particle.h" + +#if OPENVDB == 1 +# include "openvdb/openvdb.h" +# include <openvdb/points/PointConversion.h> +# include <openvdb/points/PointCount.h> +#endif + +#define POSITION_NAME "P" +#define FLAG_NAME "U" + +using namespace std; + +namespace Manta { + +#if OPENVDB == 1 + +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); + } +} + +template<class VDBType, class T> +void importVDB(VDBType vdbValue, ParticleDataImpl<T> *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<ParticleDataBase *> &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<openvdb::Vec3s> positionHandle(positionArray); + openvdb::points::AttributeHandle<int> flagHandle(flagArray); + + // Get vdb handles to pdata objects in pdata list + std::vector<std::tuple<int, openvdb::points::AttributeHandle<int>>> pDataHandlesInt; + std::vector<std::tuple<int, openvdb::points::AttributeHandle<float>>> pDataHandlesReal; + std::vector<std::tuple<int, openvdb::points::AttributeHandle<openvdb::Vec3s>>> + 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<int> intHandle(pDataArray); + std::tuple<int, openvdb::points::AttributeHandle<int>> tuple = std::make_tuple(pDataIndex, + intHandle); + pDataHandlesInt.push_back(tuple); + } + else if (pdb->getType() == ParticleDataBase::TypeReal) { + openvdb::points::AttributeHandle<float> floatHandle(pDataArray); + std::tuple<int, openvdb::points::AttributeHandle<float>> tuple = std::make_tuple( + pDataIndex, floatHandle); + pDataHandlesReal.push_back(tuple); + } + else if (pdb->getType() == ParticleDataBase::TypeVec3) { + openvdb::points::AttributeHandle<openvdb::Vec3s> vec3Handle(pDataArray); + std::tuple<int, openvdb::points::AttributeHandle<openvdb::Vec3s>> 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<int, openvdb::points::AttributeHandle<int>> tuple : pDataHandlesInt) { + int pDataIndex = std::get<0>(tuple); + int vdbValue = std::get<1>(tuple).get(*indexIter); + + ParticleDataImpl<int> *pdi = dynamic_cast<ParticleDataImpl<int> *>(toPData[pDataIndex]); + importVDB<int, int>(vdbValue, pdi, cnt, voxelSize); + } + for (std::tuple<int, openvdb::points::AttributeHandle<float>> tuple : pDataHandlesReal) { + int pDataIndex = std::get<0>(tuple); + float vdbValue = std::get<1>(tuple).get(*indexIter); + + ParticleDataImpl<Real> *pdi = dynamic_cast<ParticleDataImpl<Real> *>(toPData[pDataIndex]); + importVDB<float, Real>(vdbValue, pdi, cnt, voxelSize); + } + for (std::tuple<int, openvdb::points::AttributeHandle<openvdb::Vec3s>> tuple : + pDataHandlesVec3) { + int pDataIndex = std::get<0>(tuple); + openvdb::Vec3f voxelPosition = std::get<1>(tuple).get(*indexIter); + + ParticleDataImpl<Vec3> *pdi = dynamic_cast<ParticleDataImpl<Vec3> *>(toPData[pDataIndex]); + importVDB<openvdb::Vec3s, Vec3>(voxelPosition, pdi, cnt, voxelSize); + } + ++cnt; + } + } +} + +template<class GridType> +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<class T, class GridType> typename GridType::Ptr exportVDB(Grid<T> *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<class MantaType, class VDBType> +void exportVDB(ParticleDataImpl<MantaType> *from, + openvdb::points::PointDataGrid::Ptr to, + openvdb::tools::PointIndexGrid::Ptr pIndex, + bool skipDeletedParts) +{ + std::vector<VDBType> vdbValues; + std::string name = from->getName(); + + FOR_PARTS(*from) + { + // Optionally, skip exporting particles that have been marked as deleted + BasicParticleSystem *pp = dynamic_cast<BasicParticleSystem *>(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<VDBType, openvdb::points::NullCodec>::attributeType(); + openvdb::points::appendAttribute(to->tree(), name, attribute); + + // Create a wrapper around the vdb values vector. + const openvdb::points::PointAttributeVector<VDBType> wrapper(vdbValues); + + // Populate the attribute on the points + openvdb::points::populateAttribute<openvdb::points::PointDataTree, + openvdb::tools::PointIndexTree, + openvdb::points::PointAttributeVector<VDBType>>( + to->tree(), pIndex->tree(), name, wrapper); +} + +openvdb::points::PointDataGrid::Ptr exportVDB(BasicParticleSystem *from, + std::vector<ParticleDataBase *> &fromPData, + bool skipDeletedParts, + float voxelSize) +{ + std::vector<openvdb::Vec3s> positions; + std::vector<int> flags; + + FOR_PARTS(*from) + { + // Optionally, skip exporting particles that have been marked as deleted + if (skipDeletedParts && !from->isActive(idx)) { + continue; + } + Vector3D<float> 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<openvdb::Vec3s> positionsWrapper(positions); + openvdb::math::Transform::Ptr transform = openvdb::math::Transform::createLinearTransform( + voxelSize); + + openvdb::tools::PointIndexGrid::Ptr pointIndexGrid = + openvdb::tools::createPointIndexGrid<openvdb::tools::PointIndexGrid>(positionsWrapper, + *transform); + + // TODO (sebbas): Use custom codec for attributes? + // using Codec = openvdb::points::FixedPointCodec</*1-byte=*/false, openvdb::points::UnitRange>; + openvdb::points::PointDataGrid::Ptr to = + openvdb::points::createPointDataGrid<openvdb::points::NullCodec /*Codec*/, + openvdb::points::PointDataGrid>( + *pointIndexGrid, positionsWrapper, *transform); + + openvdb::NamePair flagAttribute = + openvdb::points::TypedAttributeArray<int, + openvdb::points::NullCodec /*Codec*/>::attributeType(); + openvdb::points::appendAttribute(to->tree(), FLAG_NAME, flagAttribute); + // Create a wrapper around the flag vector. + openvdb::points::PointAttributeVector<int> flagWrapper(flags); + // Populate the "flag" attribute on the points + openvdb::points::populateAttribute<openvdb::points::PointDataTree, + openvdb::tools::PointIndexTree, + openvdb::points::PointAttributeVector<int>>( + 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<int> *pdi = dynamic_cast<ParticleDataImpl<int> *>(pdb); + exportVDB<int, int>(pdi, to, pointIndexGrid, skipDeletedParts); + } + else if (pdb->getType() == ParticleDataBase::TypeReal) { + debMsg("Writing real particle data '" << pdb->getName() << "'", 1); + ParticleDataImpl<Real> *pdi = dynamic_cast<ParticleDataImpl<Real> *>(pdb); + exportVDB<Real, float>(pdi, to, pointIndexGrid, skipDeletedParts); + } + else if (pdb->getType() == ParticleDataBase::TypeVec3) { + debMsg("Writing Vec3 particle data '" << pdb->getName() << "'", 1); + ParticleDataImpl<Vec3> *pdi = dynamic_cast<ParticleDataImpl<Vec3> *>(pdb); + exportVDB<Vec3, openvdb::Vec3s>(pdi, to, pointIndexGrid, skipDeletedParts); + } + else { + errMsg("exportVDB: unknown ParticleDataBase type"); + } + } + return to; +} + +static void registerCustomCodecs() +{ + using Codec = openvdb::points::FixedPointCodec</*1-byte=*/false, openvdb::points::UnitRange>; + openvdb::points::TypedAttributeArray<int, Codec>::registerType(); +} + +int writeObjectsVDB(const string &filename, + std::vector<PbClass *> *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<ParticleDataBase *> pdbBuffer; + + for (std::vector<PbClass *>::iterator iter = objects->begin(); iter != objects->end(); ++iter) { + openvdb::GridClass gClass = openvdb::GRID_UNKNOWN; + openvdb::GridBase::Ptr vdbGrid; + + PbClass *object = dynamic_cast<PbClass *>(*iter); + const Real dx = object->getParent()->getDx(); + const Real voxelSize = worldSize * dx; + const string objectName = object->getName(); + + if (GridBase *mantaGrid = dynamic_cast<GridBase *>(*iter)) { + + 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); + 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<Real> *mantaRealGrid = (Grid<Real> *)mantaGrid; + vdbGrid = exportVDB<Real, openvdb::FloatGrid>(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<Vec3> *mantaVec3Grid = (Grid<Vec3> *)mantaGrid; + vdbGrid = exportVDB<Vec3, openvdb::Vec3SGrid>(mantaVec3Grid); + gridsVDB.push_back(vdbGrid); + } + else { + errMsg("writeObjectsVDB: unknown grid type"); + return 0; + } + } + else if (BasicParticleSystem *mantaPP = dynamic_cast<BasicParticleSystem *>(*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<ParticleDataBase *>(*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<openvdb::GridBase>(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<PbClass *> *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<ParticleDataBase *> pdbBuffer; + + for (std::vector<PbClass *>::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<PbClass *>(*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<ParticleDataBase *>(*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<GridBase *>(*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<openvdb::Int32Grid>(vdbGrid); + Grid<int> *mantaIntGrid = (Grid<int> *)mantaGrid; + importVDB<openvdb::Int32Grid, int>(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<openvdb::FloatGrid>(vdbGrid); + Grid<Real> *mantaRealGrid = (Grid<Real> *)mantaGrid; + importVDB<openvdb::FloatGrid, Real>(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<openvdb::Vec3SGrid>(vdbGrid); + Grid<Vec3> *mantaVec3Grid = (Grid<Vec3> *)mantaGrid; + importVDB<openvdb::Vec3SGrid, Vec3>(vdbVec3Grid, mantaVec3Grid); + } + else { + errMsg("readObjectsVDB: unknown grid type"); + return 0; + } + } + else if (BasicParticleSystem *mantaPP = dynamic_cast<BasicParticleSystem *>(*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<openvdb::points::PointDataGrid>(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, int>(int vdbValue, + ParticleDataImpl<int> *to, + int index, + float voxelSize = 1.0); +template void importVDB<float, Real>(float vdbValue, + ParticleDataImpl<Real> *to, + int index, + float voxelSize = 1.0); +template void importVDB<openvdb::Vec3f, Vec3>(openvdb::Vec3s vdbValue, + ParticleDataImpl<Vec3> *to, + int index, + float voxelSize = 1.0); + +void importVDB(openvdb::points::PointDataGrid::Ptr from, + BasicParticleSystem *to, + std::vector<ParticleDataBase *> &toPData, + float voxelSize = 1.0); +template void importVDB<openvdb::Int32Grid, int>(openvdb::Int32Grid::Ptr from, Grid<int> *to); +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); + +openvdb::points::PointDataGrid::Ptr exportVDB(BasicParticleSystem *from, + std::vector<ParticleDataBase *> &fromPData, + bool skipDeletedParts = false, + float voxelSize = 1.0); +template void exportVDB<int, int>(ParticleDataImpl<int> *from, + openvdb::points::PointDataGrid::Ptr to, + openvdb::tools::PointIndexGrid::Ptr pIndex, + bool skipDeletedParts = false); +template void exportVDB<Real, float>(ParticleDataImpl<Real> *from, + openvdb::points::PointDataGrid::Ptr to, + openvdb::tools::PointIndexGrid::Ptr pIndex, + bool skipDeletedParts = false); +template void exportVDB<Vec3, openvdb::Vec3s>(ParticleDataImpl<Vec3> *from, + openvdb::points::PointDataGrid::Ptr to, + openvdb::tools::PointIndexGrid::Ptr pIndex, + bool skipDeletedParts = false); + +#else + +int writeObjectsVDB(const string &filename, + std::vector<PbClass *> *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<PbClass *> *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<PbClass *> &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<bool>("notiming", -1, 0); + pbPreparePlugin(parent, "load", !noTiming); + PyObject *_retval = 0; + { + ArgLocker _lock; + const string &name = _args.get<string>("name", 0, &_lock); + std::vector<PbClass *> &objects = *_args.getPtr<std::vector<PbClass *>>( + "objects", 1, &_lock); + float worldSize = _args.getOpt<float>("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<PbClass *> &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<bool>("notiming", -1, 0); + pbPreparePlugin(parent, "save", !noTiming); + PyObject *_retval = 0; + { + ArgLocker _lock; + const string &name = _args.get<string>("name", 0, &_lock); + std::vector<PbClass *> &objects = *_args.getPtr<std::vector<PbClass *>>( + "objects", 1, &_lock); + float worldSize = _args.getOpt<float>("worldSize", 2, 1.0, &_lock); + bool skipDeletedParts = _args.getOpt<bool>("skipDeletedParts", 3, false, &_lock); + int compression = _args.getOpt<int>("compression", 4, COMPRESSION_ZIP, &_lock); + bool precisionHalf = _args.getOpt<bool>("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 <string> +#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 T> class Grid; template<class T> class Grid4d; class BasicParticleSystem; template<class T> class ParticleDataImpl; template<class T> 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<class T> void writeGridRaw(const std::string &name, Grid<T> *grid); -template<class T> void writeGridUni(const std::string &name, Grid<T> *grid); -template<class T> void writeGridVol(const std::string &name, Grid<T> *grid); -template<class T> void writeGridTxt(const std::string &name, Grid<T> *grid); - -#if OPENVDB == 1 -template<class T> void writeGridVDB(const std::string &name, Grid<T> *grid); -template<class T> void readGridVDB(const std::string &name, Grid<T> *grid); -#endif // OPENVDB==1 -template<class T> void writeGridNumpy(const std::string &name, Grid<T> *grid); -template<class T> void readGridNumpy(const std::string &name, Grid<T> *grid); - -template<class T> void readGridUni(const std::string &name, Grid<T> *grid); -template<class T> void readGridRaw(const std::string &name, Grid<T> *grid); -template<class T> void readGridVol(const std::string &name, Grid<T> *grid); - -template<class T> void writeGrid4dUni(const std::string &name, Grid4d<T> *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<class T> int readGridUni(const std::string &name, Grid<T> *grid); +template<class T> int readGridRaw(const std::string &name, Grid<T> *grid); +template<class T> int readGridVol(const std::string &name, Grid<T> *grid); +int readGridsRaw(const std::string &name, std::vector<PbClass *> *grids); +int readGridsUni(const std::string &name, std::vector<PbClass *> *grids); +int readGridsVol(const std::string &name, std::vector<PbClass *> *grids); +int readGridsTxt(const std::string &name, std::vector<PbClass *> *grids); + +template<class T> int writeGridRaw(const std::string &name, Grid<T> *grid); +template<class T> int writeGridUni(const std::string &name, Grid<T> *grid); +template<class T> int writeGridVol(const std::string &name, Grid<T> *grid); +template<class T> int writeGridTxt(const std::string &name, Grid<T> *grid); +int writeGridsRaw(const std::string &name, std::vector<PbClass *> *grids); +int writeGridsUni(const std::string &name, std::vector<PbClass *> *grids); +int writeGridsVol(const std::string &name, std::vector<PbClass *> *grids); +int writeGridsTxt(const std::string &name, std::vector<PbClass *> *grids); + +// OpenVDB +int writeObjectsVDB(const std::string &filename, + std::vector<PbClass *> *objects, + float scale = 1.0, + bool skipDeletedParts = false, + int compression = COMPRESSION_ZIP, + bool precisionHalf = true); +int readObjectsVDB(const std::string &filename, + std::vector<PbClass *> *objects, + float scale = 1.0); + +// Numpy +template<class T> int writeGridNumpy(const std::string &name, Grid<T> *grid); +template<class T> int readGridNumpy(const std::string &name, Grid<T> *grid); + +int writeGridsNumpy(const std::string &name, std::vector<PbClass *> *grids); +int readGridsNumpy(const std::string &name, std::vector<PbClass *> *grids); + +// 4D Grids +template<class T> int writeGrid4dUni(const std::string &name, Grid4d<T> *grid); template<class T> -void readGrid4dUni(const std::string &name, - Grid4d<T> *grid, - int readTslice = -1, - Grid4d<T> *slice = NULL, - void **fileHandle = NULL); +int readGrid4dUni(const std::string &name, + Grid4d<T> *grid, + int readTslice = -1, + Grid4d<T> *slice = NULL, + void **fileHandle = NULL); void readGrid4dUniCleanup(void **fileHandle); -template<class T> void writeGrid4dRaw(const std::string &name, Grid4d<T> *grid); -template<class T> void readGrid4dRaw(const std::string &name, Grid4d<T> *grid); +template<class T> int writeGrid4dRaw(const std::string &name, Grid4d<T> *grid); +template<class T> int readGrid4dRaw(const std::string &name, Grid4d<T> *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<class T> void writePdataUni(const std::string &name, ParticleDataImpl<T> *pdata); -template<class T> void readPdataUni(const std::string &name, ParticleDataImpl<T> *pdata); +template<class T> int writePdataUni(const std::string &name, ParticleDataImpl<T> *pdata); +template<class T> int readPdataUni(const std::string &name, ParticleDataImpl<T> *pdata); -template<class T> void writeMdataUni(const std::string &name, MeshDataImpl<T> *mdata); -template<class T> void readMdataUni(const std::string &name, MeshDataImpl<T> *mdata); +// Mesh data +template<class T> int writeMdataUni(const std::string &name, MeshDataImpl<T> *mdata); +template<class T> int readMdataUni(const std::string &name, MeshDataImpl<T> *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<class S, class T> void convertFrom(S &in, T *out); +template<class S, class T> void convertTo(S *out, T &in); +#endif } // namespace Manta diff --git a/extern/mantaflow/preprocessed/gitinfo.h b/extern/mantaflow/preprocessed/gitinfo.h index 023974fd6cd..ad7ce45cbce 100644 --- a/extern/mantaflow/preprocessed/gitinfo.h +++ b/extern/mantaflow/preprocessed/gitinfo.h @@ -1,3 +1,3 @@ -#define MANTA_GIT_VERSION "commit b61bf9efa7a1d8ca98635076a7e9f2c4dacb2914" +#define MANTA_GIT_VERSION "commit 2c83bddc59cd5140e5dd91b172167a7cba9d4960" diff --git a/extern/mantaflow/preprocessed/grid.cpp b/extern/mantaflow/preprocessed/grid.cpp index 0ea3afb91f4..76716beb1ac 100644 --- a/extern/mantaflow/preprocessed/grid.cpp +++ b/extern/mantaflow/preprocessed/grid.cpp @@ -122,48 +122,52 @@ template<class T> void Grid<T>::swap(Grid<T> &other) mData = dswap; } -template<class T> void Grid<T>::load(string name) +template<class T> int Grid<T>::load(string name) { 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") - readGridRaw(name, this); + return readGridRaw(name, this); else if (ext == ".uni") - readGridUni(name, this); + return readGridUni(name, this); else if (ext == ".vol") - readGridVol(name, this); + return readGridVol(name, this); else if (ext == ".npz") - readGridNumpy(name, this); -#if OPENVDB == 1 - else if (ext == ".vdb") - readGridVDB(name, this); -#endif // OPENVDB==1 + return readGridNumpy(name, this); + else if (ext == ".vdb") { + std::vector<PbClass *> grids; + grids.push_back(this); + return readObjectsVDB(name, &grids); + } else errMsg("file '" + name + "' filetype not supported"); + return 0; } -template<class T> void Grid<T>::save(string name) +template<class T> int Grid<T>::save(string name) { 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") - writeGridRaw(name, this); + return writeGridRaw(name, this); else if (ext == ".uni") - writeGridUni(name, this); + return writeGridUni(name, this); else if (ext == ".vol") - writeGridVol(name, this); -#if OPENVDB == 1 - else if (ext == ".vdb") - writeGridVDB(name, this); -#endif // OPENVDB==1 + return writeGridVol(name, this); else if (ext == ".npz") - writeGridNumpy(name, this); + return writeGridNumpy(name, this); + else if (ext == ".vdb") { + std::vector<PbClass *> grids; + grids.push_back(this); + return writeObjectsVDB(name, &grids); + } else if (ext == ".txt") - writeGridTxt(name, this); + return writeGridTxt(name, this); else errMsg("file '" + name + "' filetype not supported"); + return 0; } //****************************************************************************** diff --git a/extern/mantaflow/preprocessed/grid.h b/extern/mantaflow/preprocessed/grid.h index fe386cfc269..a7aac80891a 100644 --- a/extern/mantaflow/preprocessed/grid.h +++ b/extern/mantaflow/preprocessed/grid.h @@ -409,7 +409,7 @@ template<class T> class Grid : public GridBase { typedef T BASETYPE; typedef GridBase BASETYPE_GRID; - void save(std::string name); + int save(std::string name); static PyObject *_W_10(PyObject *_self, PyObject *_linargs, PyObject *_kwds) { try { @@ -422,8 +422,7 @@ template<class T> class Grid : public GridBase { ArgLocker _lock; std::string name = _args.get<std::string>("name", 0, &_lock); pbo->_args.copy(_args); - _retval = getPyNone(); - pbo->save(name); + _retval = toPy(pbo->save(name)); pbo->_args.check(); } pbFinalizePlugin(pbo->getParent(), "Grid::save", !noTiming); @@ -435,7 +434,7 @@ template<class T> class Grid : public GridBase { } } - void load(std::string name); + int load(std::string name); static PyObject *_W_11(PyObject *_self, PyObject *_linargs, PyObject *_kwds) { try { @@ -448,8 +447,7 @@ template<class T> class Grid : public GridBase { ArgLocker _lock; std::string name = _args.get<std::string>("name", 0, &_lock); pbo->_args.copy(_args); - _retval = getPyNone(); - pbo->load(name); + _retval = toPy(pbo->load(name)); pbo->_args.check(); } pbFinalizePlugin(pbo->getParent(), "Grid::load", !noTiming); @@ -554,6 +552,12 @@ template<class T> class Grid : public GridBase { return mData[idx]; } + //! set data + inline void set(int i, int j, int k, T &val) + { + mData[index(i, j, k)] = val; + } + // interpolated access inline T getInterpolated(const Vec3 &pos) const { diff --git a/extern/mantaflow/preprocessed/grid4d.cpp b/extern/mantaflow/preprocessed/grid4d.cpp index 41d69b2d33a..48f80d90b9f 100644 --- a/extern/mantaflow/preprocessed/grid4d.cpp +++ b/extern/mantaflow/preprocessed/grid4d.cpp @@ -121,30 +121,32 @@ template<class T> void Grid4d<T>::swap(Grid4d<T> &other) mData = dswap; } -template<class T> void Grid4d<T>::load(string name) +template<class T> int Grid4d<T>::load(string name) { 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 == ".uni") - readGrid4dUni(name, this); + return readGrid4dUni(name, this); else if (ext == ".raw") - readGrid4dRaw(name, this); + return readGrid4dRaw(name, this); else errMsg("file '" + name + "' filetype not supported"); + return 0; } -template<class T> void Grid4d<T>::save(string name) +template<class T> int Grid4d<T>::save(string name) { 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 == ".uni") - writeGrid4dUni(name, this); + return writeGrid4dUni(name, this); else if (ext == ".raw") - writeGrid4dRaw(name, this); + return writeGrid4dRaw(name, this); else errMsg("file '" + name + "' filetype not supported"); + return 0; } //****************************************************************************** diff --git a/extern/mantaflow/preprocessed/grid4d.h b/extern/mantaflow/preprocessed/grid4d.h index c3a98788da3..ee36c681ec5 100644 --- a/extern/mantaflow/preprocessed/grid4d.h +++ b/extern/mantaflow/preprocessed/grid4d.h @@ -372,7 +372,7 @@ template<class T> class Grid4d : public Grid4dBase { typedef T BASETYPE; typedef Grid4dBase BASETYPE_GRID; - void save(std::string name); + int save(std::string name); static PyObject *_W_9(PyObject *_self, PyObject *_linargs, PyObject *_kwds) { try { @@ -385,8 +385,7 @@ template<class T> class Grid4d : public Grid4dBase { ArgLocker _lock; std::string name = _args.get<std::string>("name", 0, &_lock); pbo->_args.copy(_args); - _retval = getPyNone(); - pbo->save(name); + _retval = toPy(pbo->save(name)); pbo->_args.check(); } pbFinalizePlugin(pbo->getParent(), "Grid4d::save", !noTiming); @@ -398,7 +397,7 @@ template<class T> class Grid4d : public Grid4dBase { } } - void load(std::string name); + int load(std::string name); static PyObject *_W_10(PyObject *_self, PyObject *_linargs, PyObject *_kwds) { try { @@ -411,8 +410,7 @@ template<class T> class Grid4d : public Grid4dBase { ArgLocker _lock; std::string name = _args.get<std::string>("name", 0, &_lock); pbo->_args.copy(_args); - _retval = getPyNone(); - pbo->load(name); + _retval = toPy(pbo->load(name)); pbo->_args.check(); } pbFinalizePlugin(pbo->getParent(), "Grid4d::load", !noTiming); diff --git a/extern/mantaflow/preprocessed/particle.cpp b/extern/mantaflow/preprocessed/particle.cpp index 41af5d3ba81..c719fc8f27d 100644 --- a/extern/mantaflow/preprocessed/particle.cpp +++ b/extern/mantaflow/preprocessed/particle.cpp @@ -214,20 +214,26 @@ void BasicParticleSystem::writeParticlesRawVelocityGz(const string name) const #endif } -void BasicParticleSystem::load(const string name) +int BasicParticleSystem::load(const string name) { 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 == ".uni") - readParticlesUni(name, this); + return readParticlesUni(name, this); + else if (ext == ".vdb") { + std::vector<PbClass *> parts; + parts.push_back(this); + return readObjectsVDB(name, &parts); + } else if (ext == ".raw") // raw = uni for now - readParticlesUni(name, this); + return readParticlesUni(name, this); else errMsg("particle '" + name + "' filetype not supported for loading"); + return 0; } -void BasicParticleSystem::save(const string name) const +int BasicParticleSystem::save(const string name) { if (name.find_last_of('.') == string::npos) errMsg("file '" + name + "' does not have an extension"); @@ -235,16 +241,22 @@ void BasicParticleSystem::save(const string name) const if (ext == ".txt") this->writeParticlesText(name); else if (ext == ".uni") - writeParticlesUni(name, this); + return writeParticlesUni(name, this); else if (ext == ".raw") // raw = uni for now - writeParticlesUni(name, this); - // raw data formats, very basic for simple data transfer to other programs + return writeParticlesUni(name, this); + else if (ext == ".vdb") { + std::vector<PbClass *> parts; + parts.push_back(this); + return writeObjectsVDB(name, &parts); + // raw data formats, very basic for simple data transfer to other programs + } else if (ext == ".posgz") this->writeParticlesRawPositionsGz(name); else if (ext == ".velgz") this->writeParticlesRawVelocityGz(name); else errMsg("particle '" + name + "' filetype not supported for saving"); + return 0; } void BasicParticleSystem::printParts(IndexInt start, IndexInt stop, bool printIndex) @@ -372,30 +384,42 @@ template<> void ParticleDataImpl<Vec3>::initNewValue(IndexInt idx, Vec3 pos) } } -template<typename T> void ParticleDataImpl<T>::load(string name) +template<typename T> int ParticleDataImpl<T>::load(string name) { 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 == ".uni") - readPdataUni<T>(name, this); + return readPdataUni<T>(name, this); + else if (ext == ".vdb") { + std::vector<PbClass *> parts; + parts.push_back(this); + return readObjectsVDB(name, &parts); + } else if (ext == ".raw") // raw = uni for now - readPdataUni<T>(name, this); + return readPdataUni<T>(name, this); else errMsg("particle data '" + name + "' filetype not supported for loading"); + return 0; } -template<typename T> void ParticleDataImpl<T>::save(string name) +template<typename T> int ParticleDataImpl<T>::save(string name) { 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 == ".uni") - writePdataUni<T>(name, this); + return writePdataUni<T>(name, this); + else if (ext == ".vdb") { + std::vector<PbClass *> parts; + parts.push_back(this); + return writeObjectsVDB(name, &parts); + } else if (ext == ".raw") // raw = uni for now - writePdataUni<T>(name, this); + return writePdataUni<T>(name, this); else errMsg("particle data '" + name + "' filetype not supported for saving"); + return 0; } // specializations diff --git a/extern/mantaflow/preprocessed/particle.h b/extern/mantaflow/preprocessed/particle.h index d9dd3f49c38..0be141ed26f 100644 --- a/extern/mantaflow/preprocessed/particle.h +++ b/extern/mantaflow/preprocessed/particle.h @@ -646,7 +646,7 @@ class BasicParticleSystem : public ParticleSystem<BasicParticleData> { } //! file io - void save(const std::string name) const; + int save(const std::string name); static PyObject *_W_13(PyObject *_self, PyObject *_linargs, PyObject *_kwds) { try { @@ -659,8 +659,7 @@ class BasicParticleSystem : public ParticleSystem<BasicParticleData> { ArgLocker _lock; const std::string name = _args.get<std::string>("name", 0, &_lock); pbo->_args.copy(_args); - _retval = getPyNone(); - pbo->save(name); + _retval = toPy(pbo->save(name)); pbo->_args.check(); } pbFinalizePlugin(pbo->getParent(), "BasicParticleSystem::save", !noTiming); @@ -672,7 +671,7 @@ class BasicParticleSystem : public ParticleSystem<BasicParticleData> { } } - void load(const std::string name); + int load(const std::string name); static PyObject *_W_14(PyObject *_self, PyObject *_linargs, PyObject *_kwds) { try { @@ -685,8 +684,7 @@ class BasicParticleSystem : public ParticleSystem<BasicParticleData> { ArgLocker _lock; const std::string name = _args.get<std::string>("name", 0, &_lock); pbo->_args.copy(_args); - _retval = getPyNone(); - pbo->load(name); + _retval = toPy(pbo->load(name)); pbo->_args.check(); } pbFinalizePlugin(pbo->getParent(), "BasicParticleSystem::load", !noTiming); @@ -1022,11 +1020,15 @@ class ParticleDataBase : public PbClass { return; } - //! set base pointer + //! set / get base pointer to parent particle system void setParticleSys(ParticleBase *set) { mpParticleSys = set; } + ParticleBase *getParticleSys() + { + return mpParticleSys; + } //! debugging inline void checkPartIndex(IndexInt idx) const; @@ -1094,6 +1096,13 @@ template<class T> class ParticleDataImpl : public ParticleDataBase { return mData[idx]; } + //! set data + inline void set(const IndexInt idx, T &val) + { + DEBUG_ONLY(checkPartIndex(idx)); + mData[idx] = val; + } + //! set all values to 0, note - different from particleSystem::clear! doesnt modify size of array //! (has to stay in sync with parent system) void clear(); @@ -1716,7 +1725,7 @@ template<class T> class ParticleDataImpl : public ParticleDataBase { } //! file io - void save(const std::string name); + int save(const std::string name); static PyObject *_W_46(PyObject *_self, PyObject *_linargs, PyObject *_kwds) { try { @@ -1729,8 +1738,7 @@ template<class T> class ParticleDataImpl : public ParticleDataBase { ArgLocker _lock; const std::string name = _args.get<std::string>("name", 0, &_lock); pbo->_args.copy(_args); - _retval = getPyNone(); - pbo->save(name); + _retval = toPy(pbo->save(name)); pbo->_args.check(); } pbFinalizePlugin(pbo->getParent(), "ParticleDataImpl::save", !noTiming); @@ -1742,7 +1750,7 @@ template<class T> class ParticleDataImpl : public ParticleDataBase { } } - void load(const std::string name); + int load(const std::string name); static PyObject *_W_47(PyObject *_self, PyObject *_linargs, PyObject *_kwds) { try { @@ -1755,8 +1763,7 @@ template<class T> class ParticleDataImpl : public ParticleDataBase { ArgLocker _lock; const std::string name = _args.get<std::string>("name", 0, &_lock); pbo->_args.copy(_args); - _retval = getPyNone(); - pbo->load(name); + _retval = toPy(pbo->load(name)); pbo->_args.check(); } pbFinalizePlugin(pbo->getParent(), "ParticleDataImpl::load", !noTiming); diff --git a/extern/mantaflow/preprocessed/python/defines.py.reg.cpp b/extern/mantaflow/preprocessed/python/defines.py.reg.cpp index 1866957534c..f5b439b9cff 100644 --- a/extern/mantaflow/preprocessed/python/defines.py.reg.cpp +++ b/extern/mantaflow/preprocessed/python/defines.py.reg.cpp @@ -15,7 +15,8 @@ static const Pb::Register _reg( "4\nTypeInflow = 8\nTypeOutflow = 16\nTypeStick = 64\nTypeReserved = 256\n\n# " "integration mode\nIntEuler = 0\nIntRK2 = 1\nIntRK4 = 2\n\n# CG preconditioner\nPcNone " " = 0\nPcMIC = 1\nPcMGDynamic = 2\nPcMGStatic = 3\n\n# particles\nPtypeSpray = " - "2\nPtypeBubble = 4\nPtypeFoam = 8\nPtypeTracer = 16\n\n\n\n\n"); + "2\nPtypeBubble = 4\nPtypeFoam = 8\nPtypeTracer = 16\n\n# OpenVDB export " + "flags\nCompression_None = 0\nCompression_Zip = 1\nCompression_Blosc = 2\n\n\n\n\n"); extern "C" { void PbRegister_file_0() { diff --git a/extern/mantaflow/preprocessed/registration.cpp b/extern/mantaflow/preprocessed/registration.cpp index c5bdddf4a18..6c1e68e6523 100644 --- a/extern/mantaflow/preprocessed/registration.cpp +++ b/extern/mantaflow/preprocessed/registration.cpp @@ -45,6 +45,8 @@ extern void PbRegister_printUniFileInfoString(); extern void PbRegister_getNpzFileSize(); extern void PbRegister_quantizeGrid(); extern void PbRegister_quantizeGridVec3(); +extern void PbRegister_load(); +extern void PbRegister_save(); extern void PbRegister_resetPhiInObs(); extern void PbRegister_advectSemiLagrange(); extern void PbRegister_addGravity(); @@ -238,6 +240,8 @@ void MantaEnsureRegistration() PbRegister_getNpzFileSize(); PbRegister_quantizeGrid(); PbRegister_quantizeGridVec3(); + PbRegister_load(); + PbRegister_save(); PbRegister_resetPhiInObs(); PbRegister_advectSemiLagrange(); PbRegister_addGravity(); |