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

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'extern/mantaflow/preprocessed/fileio/iovdb.cpp')
-rw-r--r--extern/mantaflow/preprocessed/fileio/iovdb.cpp153
1 files changed, 149 insertions, 4 deletions
diff --git a/extern/mantaflow/preprocessed/fileio/iovdb.cpp b/extern/mantaflow/preprocessed/fileio/iovdb.cpp
index 3641577beca..cc2d0aa508d 100644
--- a/extern/mantaflow/preprocessed/fileio/iovdb.cpp
+++ b/extern/mantaflow/preprocessed/fileio/iovdb.cpp
@@ -38,6 +38,11 @@
#define POSITION_NAME "P"
#define FLAG_NAME "U"
+#define META_BASE_RES "file_base_resolution"
+#define META_VOXEL_SIZE "file_voxel_size"
+#define META_BBOX_MAX "file_bbox_max"
+#define META_BBOX_MIN "file_bbox_min"
+
using namespace std;
namespace Manta {
@@ -388,7 +393,8 @@ int writeObjectsVDB(const string &filename,
int compression,
int precision,
float clip,
- const Grid<Real> *clipGrid)
+ const Grid<Real> *clipGrid,
+ const bool meta)
{
openvdb::initialize();
openvdb::io::File file(filename);
@@ -489,6 +495,16 @@ int writeObjectsVDB(const string &filename,
// Set additional grid attributes, e.g. name, grid class, compression level, etc.
if (vdbGrid) {
setGridOptions<openvdb::GridBase>(vdbGrid, objectName, gClass, voxelSize, precision);
+
+ // Optional metadata: Save additional simulation information per vdb object
+ if (meta) {
+ const Vec3i size = object->getParent()->getGridSize();
+ // The (dense) resolution of this grid
+ vdbGrid->insertMeta(META_BASE_RES,
+ openvdb::Vec3IMetadata(openvdb::Vec3i(size.x, size.y, size.z)));
+ // Length of one voxel side
+ vdbGrid->insertMeta(META_VOXEL_SIZE, openvdb::FloatMetadata(voxelSize));
+ }
}
}
@@ -533,6 +549,44 @@ int writeObjectsVDB(const string &filename,
return 1;
}
+static void clearAll(std::vector<PbClass *> *objects, std::vector<ParticleDataBase *> pdbBuffer)
+{
+ // Clear all data loaded into manta objects (e.g. during IO error)
+ for (std::vector<PbClass *>::iterator iter = objects->begin(); iter != objects->end(); ++iter) {
+ if (GridBase *mantaGrid = dynamic_cast<GridBase *>(*iter)) {
+ if (mantaGrid->getType() & GridBase::TypeInt) {
+ Grid<int> *mantaIntGrid = (Grid<int> *)mantaGrid;
+ mantaIntGrid->clear();
+ }
+ else if (mantaGrid->getType() & GridBase::TypeReal) {
+ Grid<Real> *mantaRealGrid = (Grid<Real> *)mantaGrid;
+ mantaRealGrid->clear();
+ }
+ else if (mantaGrid->getType() & GridBase::TypeVec3) {
+ Grid<Vec3> *mantaVec3Grid = (Grid<Vec3> *)mantaGrid;
+ mantaVec3Grid->clear();
+ }
+ }
+ else if (BasicParticleSystem *mantaPP = dynamic_cast<BasicParticleSystem *>(*iter)) {
+ mantaPP->clear();
+ }
+ }
+ for (ParticleDataBase *pdb : pdbBuffer) {
+ if (pdb->getType() == ParticleDataBase::TypeInt) {
+ ParticleDataImpl<int> *mantaPDataInt = (ParticleDataImpl<int> *)pdb;
+ mantaPDataInt->clear();
+ }
+ else if (pdb->getType() == ParticleDataBase::TypeReal) {
+ ParticleDataImpl<Real> *mantaPDataReal = (ParticleDataImpl<Real> *)pdb;
+ mantaPDataReal->clear();
+ }
+ else if (pdb->getType() == ParticleDataBase::TypeVec3) {
+ ParticleDataImpl<Vec3> *mantaPDataVec3 = (ParticleDataImpl<Vec3> *)pdb;
+ mantaPDataVec3->clear();
+ }
+ }
+}
+
int readObjectsVDB(const string &filename, std::vector<PbClass *> *objects, float worldSize)
{
@@ -561,6 +615,9 @@ int readObjectsVDB(const string &filename, std::vector<PbClass *> *objects, floa
// A buffer to store a handle to pData objects. These will be read alongside a particle system.
std::vector<ParticleDataBase *> pdbBuffer;
+ // Count how many objects could not be read correctly
+ int readFailure = 0;
+
for (std::vector<PbClass *>::iterator iter = objects->begin(); iter != objects->end(); ++iter) {
if (gridsVDB.empty()) {
@@ -568,11 +625,12 @@ int readObjectsVDB(const string &filename, std::vector<PbClass *> *objects, floa
}
// 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);
+ const bool onlyGrid = (gridsVDB.size() == 1);
PbClass *object = dynamic_cast<PbClass *>(*iter);
const Real dx = object->getParent()->getDx();
- const Real voxelSize = worldSize * dx;
+ const Vec3i origRes = object->getParent()->getGridSize();
+ Real voxelSize = worldSize * dx;
// Particle data objects are treated separately - buffered and inserted when reading the
// particle system
@@ -596,6 +654,81 @@ int readObjectsVDB(const string &filename, std::vector<PbClass *> *objects, floa
if (!nameMatch && !onlyGrid) {
continue;
}
+
+ // Metadata: If present in the file, meta data will be parsed into these fields
+ Real metaVoxelSize(0);
+ Vec3i metaRes(0), metaBBoxMax(0), metaBBoxMin(0);
+
+ // Loop to load all meta data that we care about
+ for (openvdb::MetaMap::MetaIterator iter = vdbGrid->beginMeta(); iter != vdbGrid->endMeta();
+ ++iter) {
+ const std::string &name = iter->first;
+ const openvdb::Metadata::Ptr value = iter->second;
+ if (name.compare(META_BASE_RES) == 0) {
+ openvdb::Vec3i tmp = static_cast<openvdb::Vec3IMetadata &>(*value).value();
+ convertFrom(tmp, &metaRes);
+ }
+ else if (name.compare(META_VOXEL_SIZE) == 0) {
+ float tmp = static_cast<openvdb::FloatMetadata &>(*value).value();
+ convertFrom(tmp, &metaVoxelSize);
+
+ voxelSize = metaVoxelSize; // Make sure to update voxel size variable (used in
+ // pointgrid's importVDB())
+ if (worldSize != 1.0)
+ debMsg(
+ "readObjectsVDB: Found voxel size in meta data. worldSize parameter will be "
+ "ignored!",
+ 1);
+ }
+ else if (name.compare(META_BBOX_MAX) == 0) {
+ openvdb::Vec3i tmp = static_cast<openvdb::Vec3IMetadata &>(*value).value();
+ convertFrom(tmp, &metaBBoxMax);
+ }
+ else if (name.compare(META_BBOX_MIN) == 0) {
+ openvdb::Vec3i tmp = static_cast<openvdb::Vec3IMetadata &>(*value).value();
+ convertFrom(tmp, &metaBBoxMin);
+ }
+ else {
+ debMsg("readObjectsVDB: Skipping unknown meta information '" << name << "'", 1);
+ }
+ }
+
+ // Compare metadata with allocated grid setup. This prevents invalid index access.
+ if (notZero(metaRes) && metaRes != origRes) {
+ debMsg("readObjectsVDB Warning: Grid '" << vdbGrid->getName()
+ << "' has not been read. Meta grid res " << metaRes
+ << " vs " << origRes << " current grid size",
+ 1);
+ readFailure++;
+ break;
+ }
+ if (notZero(metaVoxelSize) && metaVoxelSize != voxelSize) {
+ debMsg("readObjectsVDB Warning: Grid '"
+ << vdbGrid->getName() << "' has not been read. Meta voxel size "
+ << metaVoxelSize << " vs " << voxelSize << " current voxel size",
+ 1);
+ readFailure++;
+ break;
+ }
+ if (metaBBoxMax.x > origRes.x || metaBBoxMax.y > origRes.y || metaBBoxMax.z > origRes.z) {
+ debMsg("readObjectsVDB Warning: Grid '"
+ << vdbGrid->getName() << "' has not been read. Vdb bbox max " << metaBBoxMax
+ << " vs " << origRes << " current grid size",
+ 1);
+ readFailure++;
+ break;
+ }
+ const Vec3i origOrigin(0);
+ if (metaBBoxMin.x < origOrigin.x || metaBBoxMin.y < origOrigin.y ||
+ metaBBoxMin.z < origOrigin.z) {
+ debMsg("readObjectsVDB Warning: Grid '"
+ << vdbGrid->getName() << "' has not been read. Vdb bbox min " << metaBBoxMin
+ << " vs " << origOrigin << " current grid origin",
+ 1);
+ readFailure++;
+ break;
+ }
+
if (GridBase *mantaGrid = dynamic_cast<GridBase *>(*iter)) {
if (mantaGrid->getType() & GridBase::TypeInt) {
@@ -655,6 +788,17 @@ int readObjectsVDB(const string &filename, std::vector<PbClass *> *objects, floa
return 0;
}
}
+ // Do not continue loading objects in this loop if there was a read error
+ if (readFailure > 0) {
+ break;
+ }
+ }
+
+ if (readFailure > 0) {
+ // Clear all data that has already been loaded into simulation objects
+ clearAll(objects, pdbBuffer);
+ pdbBuffer.clear();
+ return 0;
}
// Give out a warning if pData items were present but could not be read due to missing particle
@@ -729,7 +873,8 @@ int writeObjectsVDB(const string &filename,
int compression,
int precision,
float clip,
- const Grid<Real> *clipGrid)
+ const Grid<Real> *clipGrid,
+ const bool meta)
{
errMsg("Cannot save to .vdb file. Mantaflow has not been built with OpenVDB support.");
return 0;