Add Chromium-only Blender WebEngine parity work
This commit is contained in:
1464
blender-5.2.0/extern/mantaflow/preprocessed/fileio/iogrids.cpp
vendored
Normal file
1464
blender-5.2.0/extern/mantaflow/preprocessed/fileio/iogrids.cpp
vendored
Normal file
File diff suppressed because it is too large
Load Diff
523
blender-5.2.0/extern/mantaflow/preprocessed/fileio/iomeshes.cpp
vendored
Normal file
523
blender-5.2.0/extern/mantaflow/preprocessed/fileio/iomeshes.cpp
vendored
Normal file
@@ -0,0 +1,523 @@
|
||||
|
||||
|
||||
// DO NOT EDIT !
|
||||
// This file is generated using the MantaFlow preprocessor (prep generate).
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* MantaFlow fluid solver framework
|
||||
* Copyright 2011-2016 Tobias Pfaff, 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 meshes to disk
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <cstdlib>
|
||||
#if NO_ZLIB != 1
|
||||
extern "C" {
|
||||
# include <zlib.h>
|
||||
}
|
||||
#endif
|
||||
|
||||
#include "mantaio.h"
|
||||
#include "grid.h"
|
||||
#include "mesh.h"
|
||||
#include "vortexsheet.h"
|
||||
#include <cstring>
|
||||
|
||||
using namespace std;
|
||||
|
||||
namespace Manta {
|
||||
|
||||
static const int STR_LEN_PDATA = 256;
|
||||
|
||||
//! mdata uni header, v3 (similar to grid header and mdata header)
|
||||
typedef struct {
|
||||
int dim; // number of vertices
|
||||
int dimX, dimY, dimZ; // underlying solver resolution (all data in local coordinates!)
|
||||
int elementType, bytesPerElement; // type id and byte size
|
||||
char info[STR_LEN_PDATA]; // mantaflow build information
|
||||
unsigned long long timestamp; // creation time
|
||||
} UniMeshHeader;
|
||||
|
||||
//*****************************************************************************
|
||||
// conversion functions for double precision
|
||||
// (note - uni files always store single prec. values)
|
||||
//*****************************************************************************
|
||||
|
||||
#if NO_ZLIB != 1
|
||||
|
||||
template<class T>
|
||||
void mdataConvertWrite(gzFile &gzf, MeshDataImpl<T> &mdata, void *ptr, UniMeshHeader &head)
|
||||
{
|
||||
errMsg("mdataConvertWrite: unknown type, not yet supported");
|
||||
}
|
||||
|
||||
template<>
|
||||
void mdataConvertWrite(gzFile &gzf, MeshDataImpl<int> &mdata, void *ptr, UniMeshHeader &head)
|
||||
{
|
||||
gzwrite(gzf, &head, sizeof(UniMeshHeader));
|
||||
gzwrite(gzf, &mdata[0], sizeof(int) * head.dim);
|
||||
}
|
||||
template<>
|
||||
void mdataConvertWrite(gzFile &gzf, MeshDataImpl<double> &mdata, void *ptr, UniMeshHeader &head)
|
||||
{
|
||||
head.bytesPerElement = sizeof(float);
|
||||
gzwrite(gzf, &head, sizeof(UniMeshHeader));
|
||||
float *ptrf = (float *)ptr;
|
||||
for (int i = 0; i < mdata.size(); ++i, ++ptrf) {
|
||||
*ptrf = (float)mdata[i];
|
||||
}
|
||||
gzwrite(gzf, ptr, sizeof(float) * head.dim);
|
||||
}
|
||||
template<>
|
||||
void mdataConvertWrite(gzFile &gzf, MeshDataImpl<Vec3> &mdata, void *ptr, UniMeshHeader &head)
|
||||
{
|
||||
head.bytesPerElement = sizeof(Vector3D<float>);
|
||||
gzwrite(gzf, &head, sizeof(UniMeshHeader));
|
||||
float *ptrf = (float *)ptr;
|
||||
for (int i = 0; i < mdata.size(); ++i) {
|
||||
for (int c = 0; c < 3; ++c) {
|
||||
*ptrf = (float)mdata[i][c];
|
||||
ptrf++;
|
||||
}
|
||||
}
|
||||
gzwrite(gzf, ptr, sizeof(Vector3D<float>) * head.dim);
|
||||
}
|
||||
|
||||
template<class T>
|
||||
void mdataReadConvert(gzFile &gzf, MeshDataImpl<T> &grid, void *ptr, int bytesPerElement)
|
||||
{
|
||||
errMsg("mdataReadConvert: unknown mdata type, not yet supported");
|
||||
}
|
||||
|
||||
template<>
|
||||
void mdataReadConvert<int>(gzFile &gzf, MeshDataImpl<int> &mdata, void *ptr, int bytesPerElement)
|
||||
{
|
||||
gzread(gzf, ptr, sizeof(int) * mdata.size());
|
||||
assertMsg(bytesPerElement == sizeof(int),
|
||||
"mdata element size doesn't match " << bytesPerElement << " vs " << sizeof(int));
|
||||
// int dont change in double precision mode - copy over
|
||||
memcpy(&(mdata[0]), ptr, sizeof(int) * mdata.size());
|
||||
}
|
||||
|
||||
template<>
|
||||
void mdataReadConvert<double>(gzFile &gzf,
|
||||
MeshDataImpl<double> &mdata,
|
||||
void *ptr,
|
||||
int bytesPerElement)
|
||||
{
|
||||
gzread(gzf, ptr, sizeof(float) * mdata.size());
|
||||
assertMsg(bytesPerElement == sizeof(float),
|
||||
"mdata element size doesn't match " << bytesPerElement << " vs " << sizeof(float));
|
||||
float *ptrf = (float *)ptr;
|
||||
for (int i = 0; i < mdata.size(); ++i, ++ptrf) {
|
||||
mdata[i] = double(*ptrf);
|
||||
}
|
||||
}
|
||||
|
||||
template<>
|
||||
void mdataReadConvert<Vec3>(gzFile &gzf, MeshDataImpl<Vec3> &mdata, void *ptr, int bytesPerElement)
|
||||
{
|
||||
gzread(gzf, ptr, sizeof(Vector3D<float>) * mdata.size());
|
||||
assertMsg(bytesPerElement == sizeof(Vector3D<float>),
|
||||
"mdata element size doesn't match " << bytesPerElement << " vs "
|
||||
<< sizeof(Vector3D<float>));
|
||||
float *ptrf = (float *)ptr;
|
||||
for (int i = 0; i < mdata.size(); ++i) {
|
||||
Vec3 v;
|
||||
for (int c = 0; c < 3; ++c) {
|
||||
v[c] = double(*ptrf);
|
||||
ptrf++;
|
||||
}
|
||||
mdata[i] = v;
|
||||
}
|
||||
}
|
||||
|
||||
#endif // NO_ZLIB!=1
|
||||
|
||||
//*****************************************************************************
|
||||
// mesh data
|
||||
//*****************************************************************************
|
||||
|
||||
int readBobjFile(const string &name, Mesh *mesh, bool append)
|
||||
{
|
||||
debMsg("reading mesh file " << name, 1);
|
||||
if (!append)
|
||||
mesh->clear();
|
||||
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) {
|
||||
errMsg("readBobj: unable to open file");
|
||||
return 0;
|
||||
}
|
||||
|
||||
// read vertices
|
||||
int num = 0;
|
||||
gzread(gzf, &num, sizeof(int));
|
||||
mesh->resizeNodes(num);
|
||||
debMsg("read mesh , verts " << num, 1);
|
||||
for (int i = 0; i < num; i++) {
|
||||
Vector3D<float> pos;
|
||||
gzread(gzf, &pos.value[0], sizeof(float) * 3);
|
||||
mesh->nodes(i).pos = toVec3(pos);
|
||||
|
||||
// convert to grid space
|
||||
mesh->nodes(i).pos /= dx;
|
||||
mesh->nodes(i).pos += gs * 0.5;
|
||||
}
|
||||
|
||||
// normals
|
||||
num = 0;
|
||||
gzread(gzf, &num, sizeof(int));
|
||||
for (int i = 0; i < num; i++) {
|
||||
Vector3D<float> pos;
|
||||
gzread(gzf, &pos.value[0], sizeof(float) * 3);
|
||||
mesh->nodes(i).normal = toVec3(pos);
|
||||
}
|
||||
|
||||
// read tris
|
||||
num = 0;
|
||||
gzread(gzf, &num, sizeof(int));
|
||||
mesh->resizeTris(num);
|
||||
for (int t = 0; t < num; t++) {
|
||||
for (int j = 0; j < 3; j++) {
|
||||
int trip = 0;
|
||||
gzread(gzf, &trip, sizeof(int));
|
||||
mesh->tris(t).c[j] = trip;
|
||||
}
|
||||
}
|
||||
// note - vortex sheet info ignored for now... (see writeBobj)
|
||||
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
|
||||
}
|
||||
|
||||
int writeBobjFile(const string &name, Mesh *mesh)
|
||||
{
|
||||
debMsg("writing mesh file " << name, 1);
|
||||
#if NO_ZLIB != 1
|
||||
const Real dx = mesh->getParent()->getDx();
|
||||
const Vec3i gs = mesh->getParent()->getGridSize();
|
||||
|
||||
gzFile gzf = (gzFile)safeGzopen(name.c_str(), "wb1"); // do some compression
|
||||
if (!gzf) {
|
||||
errMsg("writeBobj: unable to open file");
|
||||
return 0;
|
||||
}
|
||||
|
||||
// write vertices
|
||||
int numVerts = mesh->numNodes();
|
||||
gzwrite(gzf, &numVerts, sizeof(int));
|
||||
for (int i = 0; i < numVerts; i++) {
|
||||
Vector3D<float> pos = toVec3f(mesh->nodes(i).pos);
|
||||
// normalize to unit cube around 0
|
||||
pos -= toVec3f(gs) * 0.5;
|
||||
pos *= dx;
|
||||
gzwrite(gzf, &pos.value[0], sizeof(float) * 3);
|
||||
}
|
||||
|
||||
// normals
|
||||
mesh->computeVertexNormals();
|
||||
gzwrite(gzf, &numVerts, sizeof(int));
|
||||
for (int i = 0; i < numVerts; i++) {
|
||||
Vector3D<float> pos = toVec3f(mesh->nodes(i).normal);
|
||||
gzwrite(gzf, &pos.value[0], sizeof(float) * 3);
|
||||
}
|
||||
|
||||
// write tris
|
||||
int numTris = mesh->numTris();
|
||||
gzwrite(gzf, &numTris, sizeof(int));
|
||||
for (int t = 0; t < numTris; t++) {
|
||||
for (int j = 0; j < 3; j++) {
|
||||
int trip = mesh->tris(t).c[j];
|
||||
gzwrite(gzf, &trip, sizeof(int));
|
||||
}
|
||||
}
|
||||
|
||||
// per vertex smoke densities
|
||||
if (mesh->getType() == Mesh::TypeVortexSheet) {
|
||||
VortexSheetMesh *vmesh = (VortexSheetMesh *)mesh;
|
||||
int densId[4] = {0, 'v', 'd', 'e'};
|
||||
gzwrite(gzf, &densId[0], sizeof(int) * 4);
|
||||
|
||||
// compute densities
|
||||
vector<float> triDensity(numTris);
|
||||
for (int tri = 0; tri < numTris; tri++) {
|
||||
Real area = vmesh->getFaceArea(tri);
|
||||
if (area > 0)
|
||||
triDensity[tri] = vmesh->sheet(tri).smokeAmount;
|
||||
}
|
||||
|
||||
// project triangle data to vertex
|
||||
vector<int> triPerVertex(numVerts);
|
||||
vector<float> density(numVerts);
|
||||
for (int tri = 0; tri < numTris; tri++) {
|
||||
for (int c = 0; c < 3; c++) {
|
||||
int vertex = mesh->tris(tri).c[c];
|
||||
density[vertex] += triDensity[tri];
|
||||
triPerVertex[vertex]++;
|
||||
}
|
||||
}
|
||||
|
||||
// averaged smoke densities
|
||||
for (int point = 0; point < numVerts; point++) {
|
||||
float dens = 0;
|
||||
if (triPerVertex[point] > 0)
|
||||
dens = density[point] / triPerVertex[point];
|
||||
gzwrite(gzf, &dens, sizeof(float));
|
||||
}
|
||||
}
|
||||
|
||||
// vertex flags
|
||||
if (mesh->getType() == Mesh::TypeVortexSheet) {
|
||||
int Id[4] = {0, 'v', 'x', 'f'};
|
||||
gzwrite(gzf, &Id[0], sizeof(int) * 4);
|
||||
|
||||
// averaged smoke densities
|
||||
for (int point = 0; point < numVerts; point++) {
|
||||
float alpha = (mesh->nodes(point).flags & Mesh::NfMarked) ? 1 : 0;
|
||||
gzwrite(gzf, &alpha, sizeof(float));
|
||||
}
|
||||
}
|
||||
|
||||
return (gzclose(gzf) == Z_OK);
|
||||
#else
|
||||
debMsg("file format not supported without zlib", 1);
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
int readObjFile(const std::string &name, Mesh *mesh, bool append)
|
||||
{
|
||||
ifstream ifs(name.c_str());
|
||||
|
||||
if (!ifs.good()) {
|
||||
errMsg("can't open file '" + name + "'");
|
||||
return 0;
|
||||
}
|
||||
|
||||
const Real dx = mesh->getParent()->getDx();
|
||||
const Vec3 gs = toVec3(mesh->getParent()->getGridSize());
|
||||
|
||||
if (!append)
|
||||
mesh->clear();
|
||||
int nodebase = mesh->numNodes();
|
||||
int cntNodes = nodebase, cntNormals = nodebase;
|
||||
|
||||
while (ifs.good() && !ifs.eof()) {
|
||||
string id;
|
||||
ifs >> id;
|
||||
|
||||
if (id[0] == '#') {
|
||||
// comment
|
||||
getline(ifs, id);
|
||||
continue;
|
||||
}
|
||||
if (id == "vt") {
|
||||
// tex coord, ignore
|
||||
}
|
||||
else if (id == "vn") {
|
||||
// normals
|
||||
if (mesh->numNodes() != cntNodes) {
|
||||
errMsg("invalid amount of nodes");
|
||||
return 0;
|
||||
}
|
||||
Node *n = &mesh->nodes(cntNormals);
|
||||
ifs >> n->normal.x >> n->normal.y >> n->normal.z;
|
||||
cntNormals++;
|
||||
}
|
||||
else if (id == "v") {
|
||||
// vertex
|
||||
Node n;
|
||||
ifs >> n.pos.x >> n.pos.y >> n.pos.z;
|
||||
// convert to grid space
|
||||
n.pos /= dx;
|
||||
n.pos += gs * 0.5;
|
||||
mesh->addNode(n);
|
||||
cntNodes++;
|
||||
}
|
||||
else if (id == "g") {
|
||||
// group
|
||||
string group;
|
||||
ifs >> group;
|
||||
}
|
||||
else if (id == "f") {
|
||||
// face
|
||||
string face;
|
||||
Triangle t;
|
||||
for (int i = 0; i < 3; i++) {
|
||||
ifs >> face;
|
||||
if (face.find('/') != string::npos)
|
||||
face = face.substr(0, face.find('/')); // ignore other indices
|
||||
int idx = atoi(face.c_str()) - 1;
|
||||
if (idx < 0) {
|
||||
errMsg("invalid face encountered");
|
||||
return 0;
|
||||
}
|
||||
idx += nodebase;
|
||||
t.c[i] = idx;
|
||||
}
|
||||
mesh->addTri(t);
|
||||
}
|
||||
else {
|
||||
// whatever, ignore
|
||||
}
|
||||
// kill rest of line
|
||||
getline(ifs, id);
|
||||
}
|
||||
ifs.close();
|
||||
return 1;
|
||||
}
|
||||
|
||||
// write regular .obj file, in line with bobj.gz output (but only verts & tris for now)
|
||||
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()) {
|
||||
errMsg("writeObjFile: can't open file " << name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
ofs << "o MantaMesh\n";
|
||||
|
||||
// write vertices
|
||||
int numVerts = mesh->numNodes();
|
||||
for (int i = 0; i < numVerts; i++) {
|
||||
Vector3D<float> pos = toVec3f(mesh->nodes(i).pos);
|
||||
// normalize to unit cube around 0
|
||||
pos -= toVec3f(gs) * 0.5;
|
||||
pos *= dx;
|
||||
ofs << "v " << pos.value[0] << " " << pos.value[1] << " " << pos.value[2] << " "
|
||||
<< "\n";
|
||||
}
|
||||
|
||||
// write normals
|
||||
for (int i = 0; i < numVerts; i++) {
|
||||
Vector3D<float> n = toVec3f(mesh->nodes(i).normal);
|
||||
ofs << "vn " << n.value[0] << " " << n.value[1] << " " << n.value[2] << " "
|
||||
<< "\n";
|
||||
}
|
||||
|
||||
// write tris
|
||||
int numTris = mesh->numTris();
|
||||
for (int t = 0; t < numTris; t++) {
|
||||
ofs << "f " << (mesh->tris(t).c[0] + 1) << " " << (mesh->tris(t).c[1] + 1) << " "
|
||||
<< (mesh->tris(t).c[2] + 1) << " "
|
||||
<< "\n";
|
||||
}
|
||||
|
||||
ofs.close();
|
||||
return 1;
|
||||
}
|
||||
|
||||
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) {
|
||||
errMsg("can't open file " << name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
char ID[5] = {0, 0, 0, 0, 0};
|
||||
gzread(gzf, ID, 4);
|
||||
|
||||
if (!strcmp(ID, "MD01")) {
|
||||
UniMeshHeader head;
|
||||
assertMsg(gzread(gzf, &head, sizeof(UniMeshHeader)) == sizeof(UniMeshHeader),
|
||||
"can't read file, no header present");
|
||||
mdata->resize(head.dim);
|
||||
|
||||
assertMsg(head.dim == mdata->size(), "mdata size doesn't match");
|
||||
# if FLOATINGPOINT_PRECISION != 1
|
||||
MeshDataImpl<T> temp(mdata->getParent());
|
||||
temp.resize(mdata->size());
|
||||
mdataReadConvert<T>(gzf, *mdata, &(temp[0]), head.bytesPerElement);
|
||||
# else
|
||||
assertMsg(((head.bytesPerElement == sizeof(T)) && (head.elementType == 1)),
|
||||
"mdata type doesn't match");
|
||||
IndexInt bytes = sizeof(T) * head.dim;
|
||||
IndexInt readBytes = gzread(gzf, &(mdata->get(0)), sizeof(T) * head.dim);
|
||||
assertMsg(bytes == readBytes,
|
||||
"can't read uni file, stream length does not match, " << bytes << " vs "
|
||||
<< readBytes);
|
||||
# endif
|
||||
}
|
||||
return (gzclose(gzf) == Z_OK);
|
||||
#else
|
||||
debMsg("file format not supported without zlib", 1);
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
template<class T> int writeMdataUni(const std::string &name, MeshDataImpl<T> *mdata)
|
||||
{
|
||||
debMsg("writing mesh data " << mdata->getName() << " to uni file " << name, 1);
|
||||
|
||||
#if NO_ZLIB != 1
|
||||
char ID[5] = "MD01";
|
||||
UniMeshHeader head;
|
||||
head.dim = mdata->size();
|
||||
head.bytesPerElement = sizeof(T);
|
||||
head.elementType = 1; // 1 for mesh data, todo - add sub types?
|
||||
snprintf(head.info, STR_LEN_PDATA, "%s", buildInfoString().c_str());
|
||||
MuTime stamp;
|
||||
head.timestamp = stamp.time;
|
||||
|
||||
gzFile gzf = (gzFile)safeGzopen(name.c_str(), "wb1"); // do some compression
|
||||
if (!gzf) {
|
||||
errMsg("can't open file " << name);
|
||||
return 0;
|
||||
}
|
||||
gzwrite(gzf, ID, 4);
|
||||
|
||||
# if FLOATINGPOINT_PRECISION != 1
|
||||
// always write float values, even if compiled with double precision (as for grids)
|
||||
MeshDataImpl<T> temp(mdata->getParent());
|
||||
temp.resize(mdata->size());
|
||||
mdataConvertWrite(gzf, *mdata, &(temp[0]), head);
|
||||
# else
|
||||
gzwrite(gzf, &head, sizeof(UniMeshHeader));
|
||||
gzwrite(gzf, &(mdata->get(0)), sizeof(T) * head.dim);
|
||||
# endif
|
||||
return (gzclose(gzf) == Z_OK);
|
||||
|
||||
#else
|
||||
debMsg("file format not supported without zlib", 1);
|
||||
return 0;
|
||||
#endif
|
||||
};
|
||||
|
||||
// explicit instantiation
|
||||
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
|
||||
384
blender-5.2.0/extern/mantaflow/preprocessed/fileio/ioparticles.cpp
vendored
Normal file
384
blender-5.2.0/extern/mantaflow/preprocessed/fileio/ioparticles.cpp
vendored
Normal file
@@ -0,0 +1,384 @@
|
||||
|
||||
|
||||
// DO NOT EDIT !
|
||||
// This file is generated using the MantaFlow preprocessor (prep generate).
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* MantaFlow fluid solver framework
|
||||
* Copyright 2011-2016 Tobias Pfaff, 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 meshes to disk
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
#if NO_ZLIB != 1
|
||||
extern "C" {
|
||||
# include <zlib.h>
|
||||
}
|
||||
#endif
|
||||
|
||||
#include "mantaio.h"
|
||||
#include "grid.h"
|
||||
#include "particle.h"
|
||||
#include "vector4d.h"
|
||||
#include "grid4d.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
namespace Manta {
|
||||
|
||||
static const int STR_LEN_PDATA = 256;
|
||||
|
||||
//! pdata uni header, v3 (similar to grid header)
|
||||
typedef struct {
|
||||
int dim; // number of partilces
|
||||
int dimX, dimY, dimZ; // underlying solver resolution (all data in local coordinates!)
|
||||
int elementType, bytesPerElement; // type id and byte size
|
||||
char info[STR_LEN_PDATA]; // mantaflow build information
|
||||
unsigned long long timestamp; // creation time
|
||||
} UniPartHeader;
|
||||
|
||||
//*****************************************************************************
|
||||
// conversion functions for double precision
|
||||
// (note - uni files always store single prec. values)
|
||||
//*****************************************************************************
|
||||
|
||||
#if NO_ZLIB != 1
|
||||
|
||||
template<class T>
|
||||
void pdataConvertWrite(gzFile &gzf, ParticleDataImpl<T> &pdata, void *ptr, UniPartHeader &head)
|
||||
{
|
||||
errMsg("pdataConvertWrite: unknown type, not yet supported");
|
||||
}
|
||||
|
||||
template<>
|
||||
void pdataConvertWrite(gzFile &gzf, ParticleDataImpl<int> &pdata, void *ptr, UniPartHeader &head)
|
||||
{
|
||||
gzwrite(gzf, &head, sizeof(UniPartHeader));
|
||||
gzwrite(gzf, &pdata[0], sizeof(int) * head.dim);
|
||||
}
|
||||
template<>
|
||||
void pdataConvertWrite(gzFile &gzf,
|
||||
ParticleDataImpl<double> &pdata,
|
||||
void *ptr,
|
||||
UniPartHeader &head)
|
||||
{
|
||||
head.bytesPerElement = sizeof(float);
|
||||
gzwrite(gzf, &head, sizeof(UniPartHeader));
|
||||
float *ptrf = (float *)ptr;
|
||||
for (int i = 0; i < pdata.size(); ++i, ++ptrf) {
|
||||
*ptrf = (float)pdata[i];
|
||||
}
|
||||
gzwrite(gzf, ptr, sizeof(float) * head.dim);
|
||||
}
|
||||
template<>
|
||||
void pdataConvertWrite(gzFile &gzf, ParticleDataImpl<Vec3> &pdata, void *ptr, UniPartHeader &head)
|
||||
{
|
||||
head.bytesPerElement = sizeof(Vector3D<float>);
|
||||
gzwrite(gzf, &head, sizeof(UniPartHeader));
|
||||
float *ptrf = (float *)ptr;
|
||||
for (int i = 0; i < pdata.size(); ++i) {
|
||||
for (int c = 0; c < 3; ++c) {
|
||||
*ptrf = (float)pdata[i][c];
|
||||
ptrf++;
|
||||
}
|
||||
}
|
||||
gzwrite(gzf, ptr, sizeof(Vector3D<float>) * head.dim);
|
||||
}
|
||||
|
||||
template<class T>
|
||||
void pdataReadConvert(gzFile &gzf, ParticleDataImpl<T> &grid, void *ptr, int bytesPerElement)
|
||||
{
|
||||
errMsg("pdataReadConvert: unknown pdata type, not yet supported");
|
||||
}
|
||||
|
||||
template<>
|
||||
void pdataReadConvert<int>(gzFile &gzf,
|
||||
ParticleDataImpl<int> &pdata,
|
||||
void *ptr,
|
||||
int bytesPerElement)
|
||||
{
|
||||
gzread(gzf, ptr, sizeof(int) * pdata.size());
|
||||
assertMsg(bytesPerElement == sizeof(int),
|
||||
"pdata element size doesn't match " << bytesPerElement << " vs " << sizeof(int));
|
||||
// int dont change in double precision mode - copy over
|
||||
memcpy(&(pdata[0]), ptr, sizeof(int) * pdata.size());
|
||||
}
|
||||
|
||||
template<>
|
||||
void pdataReadConvert<double>(gzFile &gzf,
|
||||
ParticleDataImpl<double> &pdata,
|
||||
void *ptr,
|
||||
int bytesPerElement)
|
||||
{
|
||||
gzread(gzf, ptr, sizeof(float) * pdata.size());
|
||||
assertMsg(bytesPerElement == sizeof(float),
|
||||
"pdata element size doesn't match " << bytesPerElement << " vs " << sizeof(float));
|
||||
float *ptrf = (float *)ptr;
|
||||
for (int i = 0; i < pdata.size(); ++i, ++ptrf) {
|
||||
pdata[i] = double(*ptrf);
|
||||
}
|
||||
}
|
||||
|
||||
template<>
|
||||
void pdataReadConvert<Vec3>(gzFile &gzf,
|
||||
ParticleDataImpl<Vec3> &pdata,
|
||||
void *ptr,
|
||||
int bytesPerElement)
|
||||
{
|
||||
gzread(gzf, ptr, sizeof(Vector3D<float>) * pdata.size());
|
||||
assertMsg(bytesPerElement == sizeof(Vector3D<float>),
|
||||
"pdata element size doesn't match " << bytesPerElement << " vs "
|
||||
<< sizeof(Vector3D<float>));
|
||||
float *ptrf = (float *)ptr;
|
||||
for (int i = 0; i < pdata.size(); ++i) {
|
||||
Vec3 v;
|
||||
for (int c = 0; c < 3; ++c) {
|
||||
v[c] = double(*ptrf);
|
||||
ptrf++;
|
||||
}
|
||||
pdata[i] = v;
|
||||
}
|
||||
}
|
||||
|
||||
#endif // NO_ZLIB!=1
|
||||
|
||||
//*****************************************************************************
|
||||
// particles and particle data
|
||||
//*****************************************************************************
|
||||
|
||||
static const int PartSysSize = sizeof(Vector3D<float>) + sizeof(int);
|
||||
|
||||
int writeParticlesUni(const std::string &name, const BasicParticleSystem *parts)
|
||||
{
|
||||
debMsg("writing particles " << parts->getName() << " to uni file " << name, 1);
|
||||
|
||||
#if NO_ZLIB != 1
|
||||
char ID[5] = "PB02";
|
||||
UniPartHeader head;
|
||||
head.dim = parts->size();
|
||||
Vec3i gridSize = parts->getParent()->getGridSize();
|
||||
head.dimX = gridSize.x;
|
||||
head.dimY = gridSize.y;
|
||||
head.dimZ = gridSize.z;
|
||||
head.bytesPerElement = PartSysSize;
|
||||
head.elementType = 0; // 0 for base data
|
||||
snprintf(head.info, STR_LEN_PDATA, "%s", buildInfoString().c_str());
|
||||
MuTime stamp;
|
||||
head.timestamp = stamp.time;
|
||||
|
||||
gzFile gzf = (gzFile)safeGzopen(name.c_str(), "wb1"); // do some compression
|
||||
if (!gzf) {
|
||||
errMsg("can't open file " << name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
gzwrite(gzf, ID, 4);
|
||||
# if FLOATINGPOINT_PRECISION != 1
|
||||
// warning - hard coded conversion of byte size here...
|
||||
gzwrite(gzf, &head, sizeof(UniPartHeader));
|
||||
for (int i = 0; i < parts->size(); ++i) {
|
||||
Vector3D<float> pos = toVec3f((*parts)[i].pos);
|
||||
int flag = (*parts)[i].flag;
|
||||
gzwrite(gzf, &pos, sizeof(Vector3D<float>));
|
||||
gzwrite(gzf, &flag, sizeof(int));
|
||||
}
|
||||
# else
|
||||
assertMsg(sizeof(BasicParticleData) == PartSysSize, "particle data size doesn't match");
|
||||
gzwrite(gzf, &head, sizeof(UniPartHeader));
|
||||
gzwrite(gzf, &((*parts)[0]), PartSysSize * head.dim);
|
||||
# endif
|
||||
return (gzclose(gzf) == Z_OK);
|
||||
#else
|
||||
debMsg("file format not supported without zlib", 1);
|
||||
return 0;
|
||||
#endif
|
||||
};
|
||||
|
||||
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) {
|
||||
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
|
||||
UniPartHeader head;
|
||||
assertMsg(gzread(gzf, &head, sizeof(UniPartHeader)) == sizeof(UniPartHeader),
|
||||
"can't read file, no header present");
|
||||
assertMsg(((head.bytesPerElement == PartSysSize) && (head.elementType == 0)),
|
||||
"particle type doesn't match");
|
||||
|
||||
const Vec3i curGridSize = parts->getParent()->getGridSize();
|
||||
const Vec3i headGridSize(head.dimX, head.dimY, head.dimZ);
|
||||
# if BLENDER
|
||||
// Correct grid size is only a soft requirement in Blender
|
||||
if (headGridSize != curGridSize) {
|
||||
debMsg("readPdataUni: Grid dim doesn't match, " << headGridSize << " vs " << curGridSize, 1);
|
||||
return 0;
|
||||
}
|
||||
# else
|
||||
assertMsg(headGridSize == curGridSize,
|
||||
"readPdataUni: Grid dim doesn't match, " << headGridSize << " vs " << curGridSize);
|
||||
# endif
|
||||
|
||||
// re-allocate all data
|
||||
parts->resizeAll(head.dim);
|
||||
|
||||
assertMsg(head.dim == parts->size(), "particle size doesn't match");
|
||||
# if FLOATINGPOINT_PRECISION != 1
|
||||
for (int i = 0; i < parts->size(); ++i) {
|
||||
Vector3D<float> pos;
|
||||
int flag;
|
||||
gzread(gzf, &pos, sizeof(Vector3D<float>));
|
||||
gzread(gzf, &flag, sizeof(int));
|
||||
(*parts)[i].pos = toVec3d(pos);
|
||||
(*parts)[i].flag = flag;
|
||||
}
|
||||
# else
|
||||
assertMsg(sizeof(BasicParticleData) == PartSysSize, "particle data size doesn't match");
|
||||
IndexInt bytes = PartSysSize * head.dim;
|
||||
IndexInt readBytes = gzread(gzf, &(parts->getData()[0]), bytes);
|
||||
assertMsg(bytes == readBytes,
|
||||
"can't read uni file, stream length does not match, " << bytes << " vs "
|
||||
<< readBytes);
|
||||
# endif
|
||||
|
||||
parts->transformPositions(Vec3i(head.dimX, head.dimY, head.dimZ),
|
||||
parts->getParent()->getGridSize());
|
||||
}
|
||||
return (gzclose(gzf) == Z_OK);
|
||||
#else
|
||||
debMsg("file format not supported without zlib", 1);
|
||||
return 0;
|
||||
#endif
|
||||
};
|
||||
|
||||
template<class T> int writePdataUni(const std::string &name, ParticleDataImpl<T> *pdata)
|
||||
{
|
||||
debMsg("writing particle data " << pdata->getName() << " to uni file " << name, 1);
|
||||
|
||||
#if NO_ZLIB != 1
|
||||
char ID[5] = "PD01";
|
||||
UniPartHeader head;
|
||||
head.dim = pdata->size();
|
||||
Vec3i gridSize = pdata->getParent()->getGridSize();
|
||||
head.dimX = gridSize.x;
|
||||
head.dimY = gridSize.y;
|
||||
head.dimZ = gridSize.z;
|
||||
head.bytesPerElement = sizeof(T);
|
||||
head.elementType = 1; // 1 for particle data, todo - add sub types?
|
||||
snprintf(head.info, STR_LEN_PDATA, "%s", buildInfoString().c_str());
|
||||
MuTime stamp;
|
||||
head.timestamp = stamp.time;
|
||||
|
||||
gzFile gzf = (gzFile)safeGzopen(name.c_str(), "wb1"); // do some compression
|
||||
if (!gzf) {
|
||||
errMsg("can't open file " << name);
|
||||
return 0;
|
||||
}
|
||||
gzwrite(gzf, ID, 4);
|
||||
|
||||
# if FLOATINGPOINT_PRECISION != 1
|
||||
// always write float values, even if compiled with double precision (as for grids)
|
||||
ParticleDataImpl<T> temp(pdata->getParent());
|
||||
temp.resize(pdata->size());
|
||||
pdataConvertWrite(gzf, *pdata, &(temp[0]), head);
|
||||
# else
|
||||
gzwrite(gzf, &head, sizeof(UniPartHeader));
|
||||
gzwrite(gzf, &(pdata->get(0)), sizeof(T) * head.dim);
|
||||
# endif
|
||||
return (gzclose(gzf) == Z_OK);
|
||||
|
||||
#else
|
||||
debMsg("file format not supported without zlib", 1);
|
||||
return 0;
|
||||
#endif
|
||||
};
|
||||
|
||||
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) {
|
||||
errMsg("can't open file " << name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
char ID[5] = {0, 0, 0, 0, 0};
|
||||
gzread(gzf, ID, 4);
|
||||
|
||||
if (!strcmp(ID, "PD01")) {
|
||||
UniPartHeader head;
|
||||
assertMsg(gzread(gzf, &head, sizeof(UniPartHeader)) == sizeof(UniPartHeader),
|
||||
"can't read file, no header present");
|
||||
pdata->getParticleSys()->resize(head.dim); // ensure that parent particle system has same size
|
||||
pdata->resize(head.dim);
|
||||
|
||||
const Vec3i curGridSize = pdata->getParent()->getGridSize();
|
||||
const Vec3i headGridSize(head.dimX, head.dimY, head.dimZ);
|
||||
# if BLENDER
|
||||
// Correct grid size is only a soft requirement in Blender
|
||||
if (headGridSize != curGridSize) {
|
||||
debMsg("readPdataUni: Grid dim doesn't match, " << headGridSize << " vs " << curGridSize, 1);
|
||||
return 0;
|
||||
}
|
||||
# else
|
||||
assertMsg(headGridSize == curGridSize,
|
||||
"readPdataUni: Grid dim doesn't match, " << headGridSize << " vs " << curGridSize);
|
||||
# endif
|
||||
|
||||
assertMsg(head.dim == pdata->size(), "pdata size doesn't match");
|
||||
# if FLOATINGPOINT_PRECISION != 1
|
||||
ParticleDataImpl<T> temp(pdata->getParent());
|
||||
temp.resize(pdata->size());
|
||||
pdataReadConvert<T>(gzf, *pdata, &(temp[0]), head.bytesPerElement);
|
||||
# else
|
||||
assertMsg(((head.bytesPerElement == sizeof(T)) && (head.elementType == 1)),
|
||||
"pdata type doesn't match");
|
||||
IndexInt bytes = sizeof(T) * head.dim;
|
||||
IndexInt readBytes = gzread(gzf, &(pdata->get(0)), sizeof(T) * head.dim);
|
||||
assertMsg(bytes == readBytes,
|
||||
"can't read uni file, stream length does not match, " << bytes << " vs "
|
||||
<< readBytes);
|
||||
# endif
|
||||
}
|
||||
return (gzclose(gzf) == Z_OK);
|
||||
#else
|
||||
debMsg("file format not supported without zlib", 1);
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
// explicit instantiation
|
||||
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
|
||||
124
blender-5.2.0/extern/mantaflow/preprocessed/fileio/ioutil.cpp
vendored
Normal file
124
blender-5.2.0/extern/mantaflow/preprocessed/fileio/ioutil.cpp
vendored
Normal file
@@ -0,0 +1,124 @@
|
||||
|
||||
|
||||
// DO NOT EDIT !
|
||||
// This file is generated using the MantaFlow preprocessor (prep generate).
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* MantaFlow fluid solver framework
|
||||
* Copyright 2011-2020 Tobias Pfaff, 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
|
||||
*
|
||||
* Helper functions to handle file IO
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
#include "mantaio.h"
|
||||
|
||||
#if OPENVDB == 1
|
||||
# include "openvdb/openvdb.h"
|
||||
#endif
|
||||
|
||||
#if NO_ZLIB != 1
|
||||
extern "C" {
|
||||
# include <zlib.h>
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(WIN32) || defined(_WIN32)
|
||||
# include <windows.h>
|
||||
# include <string>
|
||||
#endif
|
||||
|
||||
using namespace std;
|
||||
|
||||
namespace Manta {
|
||||
|
||||
#if defined(WIN32) || defined(_WIN32)
|
||||
static wstring stringToWstring(const char *str)
|
||||
{
|
||||
const int length_wc = MultiByteToWideChar(CP_UTF8, 0, str, strlen(str), nullptr, 0);
|
||||
wstring strWide(length_wc, 0);
|
||||
MultiByteToWideChar(CP_UTF8, 0, str, strlen(str), &strWide[0], length_wc);
|
||||
return strWide;
|
||||
}
|
||||
#endif // WIN32==1
|
||||
|
||||
void *safeGzopen(const char *filename, const char *mode)
|
||||
{
|
||||
#if NO_ZLIB != 1
|
||||
gzFile gzfile;
|
||||
|
||||
# if defined(WIN32) || defined(_WIN32)
|
||||
wstring filenameWide = stringToWstring(filename);
|
||||
gzfile = gzopen_w(filenameWide.c_str(), mode);
|
||||
# else
|
||||
gzfile = gzopen(filename, mode);
|
||||
# endif
|
||||
|
||||
return gzfile;
|
||||
#else
|
||||
debMsg("safeGzopen not supported without zlib", 1);
|
||||
return nullptr;
|
||||
#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();
|
||||
}
|
||||
|
||||
template<> void convertFrom(openvdb::Vec3i &in, Vec3i *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 Manta
|
||||
908
blender-5.2.0/extern/mantaflow/preprocessed/fileio/iovdb.cpp
vendored
Normal file
908
blender-5.2.0/extern/mantaflow/preprocessed/fileio/iovdb.cpp
vendored
Normal file
@@ -0,0 +1,908 @@
|
||||
|
||||
|
||||
// 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"
|
||||
# include "openvdb/tools/Clip.h"
|
||||
# include "openvdb/tools/Dense.h"
|
||||
#endif
|
||||
|
||||
#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 {
|
||||
|
||||
#if OPENVDB == 1
|
||||
|
||||
template<class GridType, class T> void importVDB(typename GridType::Ptr from, Grid<T> *to)
|
||||
{
|
||||
using ValueT = typename GridType::ValueType;
|
||||
|
||||
// Check if current grid is to be read as a sparse grid, active voxels (only) will be copied
|
||||
|
||||
if (to->saveSparse()) {
|
||||
to->clear(); // Ensure that destination grid is empty before writing
|
||||
for (typename GridType::ValueOnCIter iter = from->cbeginValueOn(); iter.test(); ++iter) {
|
||||
ValueT vdbValue = *iter;
|
||||
T toMantaValue;
|
||||
convertFrom(vdbValue, &toMantaValue);
|
||||
// #91174 #124064 - Check if iteration is Voxel or Tile
|
||||
if (iter.isVoxelValue()) {
|
||||
openvdb::Coord coord = iter.getCoord();
|
||||
to->set(coord.x(), coord.y(), coord.z(), toMantaValue);
|
||||
}
|
||||
else {
|
||||
openvdb::CoordBBox bbox;
|
||||
iter.getBoundingBox(bbox);
|
||||
// If grid has 8x8x8 block with the same value, it is stored as Tile with single value.
|
||||
// We need to iterate over the bounding box and copy such value to all voxels in 8x8x8 node.
|
||||
for (openvdb::CoordBBox::Iterator<true> ijk(bbox); ijk; ++ijk) {
|
||||
openvdb::Coord coord = *ijk;
|
||||
to->set(coord.x(), coord.y(), coord.z(), toMantaValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// When importing all grid cells, using a grid accessor is usually faster than a value iterator
|
||||
else {
|
||||
typename GridType::Accessor accessor = from->getAccessor();
|
||||
FOR_IJK(*to)
|
||||
{
|
||||
openvdb::Coord xyz(i, j, k);
|
||||
ValueT vdbValue = accessor.getValue(xyz);
|
||||
T toMantaValue;
|
||||
convertFrom(vdbValue, &toMantaValue);
|
||||
to->set(i, j, k, toMantaValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template<class VDBType, class T>
|
||||
void importVDB(VDBType vdbValue, ParticleDataImpl<T> *to, int index, float voxelSize)
|
||||
{
|
||||
unusedParameter(voxelSize); // Unused for now
|
||||
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,
|
||||
int precision)
|
||||
{
|
||||
grid->setTransform(openvdb::math::Transform::createLinearTransform(voxelSize));
|
||||
grid->setGridClass(cls);
|
||||
grid->setName(name);
|
||||
grid->setSaveFloatAsHalf(precision == PRECISION_MINI || precision == PRECISION_HALF);
|
||||
}
|
||||
|
||||
template<class T, class GridType>
|
||||
typename GridType::Ptr exportVDB(Grid<T> *from, float clip, openvdb::FloatGrid::Ptr clipGrid)
|
||||
{
|
||||
using ValueT = typename GridType::ValueType;
|
||||
typename GridType::Ptr to = GridType::create(ValueT(0));
|
||||
|
||||
// Copy data from grid by creating a vdb dense structure and then copying that into a vdb grid
|
||||
// This is the fastest way to copy data for both dense and sparse grids -> if (true)
|
||||
if (true) {
|
||||
ValueT *data = (ValueT *)from->getData();
|
||||
openvdb::math::CoordBBox bbox(
|
||||
openvdb::Coord(0),
|
||||
openvdb::Coord(from->getSizeX() - 1, from->getSizeY() - 1, from->getSizeZ() - 1));
|
||||
openvdb::tools::Dense<ValueT, openvdb::tools::MemoryLayout::LayoutXYZ> dense(bbox, data);
|
||||
|
||||
// Use clip value, or (when not exporting in sparse mode) clear it in order to copy all values
|
||||
// of dense grid
|
||||
ValueT tmpClip = (from->saveSparse()) ? ValueT(clip) : ValueT(0);
|
||||
// Copy from dense to sparse grid structure considering clip value
|
||||
openvdb::tools::copyFromDense(dense, *to, tmpClip);
|
||||
|
||||
// If present, use clip grid to trim down current vdb grid even more
|
||||
if (from->saveSparse() && clipGrid && !clipGrid->empty()) {
|
||||
to = openvdb::tools::clip(*to, *clipGrid);
|
||||
}
|
||||
}
|
||||
// Alternatively, reading all grid cells with an accessor (slightly slower) is possible like this
|
||||
else {
|
||||
typename GridType::Accessor accessor = to->getAccessor();
|
||||
FOR_IJK(*from)
|
||||
{
|
||||
openvdb::Coord xyz(i, j, k);
|
||||
T fromMantaValue = (*from)(i, j, k);
|
||||
ValueT vdbValue;
|
||||
convertTo(&vdbValue, fromMantaValue);
|
||||
accessor.setValue(xyz, vdbValue);
|
||||
}
|
||||
}
|
||||
return to;
|
||||
}
|
||||
|
||||
template<class MantaType, class VDBType>
|
||||
void exportVDB(ParticleDataImpl<MantaType> *from,
|
||||
openvdb::points::PointDataGrid::Ptr to,
|
||||
openvdb::tools::PointIndexGrid::Ptr pIndex,
|
||||
bool skipDeletedParts,
|
||||
int precision)
|
||||
{
|
||||
std::vector<VDBType> vdbValues;
|
||||
std::string name = from->getName();
|
||||
|
||||
BasicParticleSystem *pp = dynamic_cast<BasicParticleSystem *>(from->getParticleSys());
|
||||
FOR_PARTS(*from)
|
||||
{
|
||||
// Optionally, skip exporting particles that have been marked as deleted
|
||||
if (skipDeletedParts && !pp->isActive(idx)) {
|
||||
continue;
|
||||
}
|
||||
MantaType fromMantaValue = (*from)[idx];
|
||||
VDBType vdbValue;
|
||||
convertTo(&vdbValue, fromMantaValue);
|
||||
vdbValues.push_back(vdbValue);
|
||||
}
|
||||
|
||||
// Use custom codec for precision of the attribute
|
||||
openvdb::NamePair attribute;
|
||||
if (precision == PRECISION_FULL) {
|
||||
attribute =
|
||||
openvdb::points::TypedAttributeArray<VDBType, openvdb::points::NullCodec>::attributeType();
|
||||
}
|
||||
else if (precision == PRECISION_HALF ||
|
||||
precision == PRECISION_MINI) { // Mini uses same precision as half for now
|
||||
attribute =
|
||||
openvdb::points::TypedAttributeArray<VDBType,
|
||||
openvdb::points::TruncateCodec>::attributeType();
|
||||
}
|
||||
else {
|
||||
errMsg("exportVDB: invalid precision level");
|
||||
}
|
||||
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,
|
||||
int precision)
|
||||
{
|
||||
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);
|
||||
|
||||
openvdb::points::PointDataGrid::Ptr to;
|
||||
openvdb::NamePair flagAttribute;
|
||||
|
||||
using CodecNull = openvdb::points::NullCodec;
|
||||
using CodecTrunc = openvdb::points::TruncateCodec;
|
||||
using CodecFixPoint = openvdb::points::FixedPointCodec<true, openvdb::points::PositionRange>;
|
||||
|
||||
// Use custom codec for precision of the particle position and the flag attribute
|
||||
if (precision == PRECISION_FULL) {
|
||||
to = openvdb::points::createPointDataGrid<CodecNull, openvdb::points::PointDataGrid>(
|
||||
*pointIndexGrid, positionsWrapper, *transform);
|
||||
flagAttribute = openvdb::points::TypedAttributeArray<int, CodecNull>::attributeType();
|
||||
}
|
||||
else if (precision == PRECISION_HALF) {
|
||||
to = openvdb::points::createPointDataGrid<CodecTrunc, openvdb::points::PointDataGrid>(
|
||||
*pointIndexGrid, positionsWrapper, *transform);
|
||||
flagAttribute = openvdb::points::TypedAttributeArray<int, CodecTrunc>::attributeType();
|
||||
}
|
||||
else if (precision == PRECISION_MINI) {
|
||||
to = openvdb::points::createPointDataGrid<CodecFixPoint, openvdb::points::PointDataGrid>(
|
||||
*pointIndexGrid, positionsWrapper, *transform);
|
||||
flagAttribute = openvdb::points::TypedAttributeArray<int, CodecTrunc>::
|
||||
attributeType(); // Use 16 bit trunc for flag for now
|
||||
}
|
||||
else {
|
||||
errMsg("exportVDB: invalid precision level");
|
||||
}
|
||||
|
||||
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, precision);
|
||||
}
|
||||
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, precision);
|
||||
}
|
||||
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, precision);
|
||||
}
|
||||
else {
|
||||
errMsg("exportVDB: unknown ParticleDataBase type");
|
||||
}
|
||||
}
|
||||
return to;
|
||||
}
|
||||
|
||||
static void registerCustomCodecs()
|
||||
{
|
||||
openvdb::points::TypedAttributeArray<int, openvdb::points::TruncateCodec>::registerType();
|
||||
openvdb::points::TypedAttributeArray<float, openvdb::points::TruncateCodec>::registerType();
|
||||
openvdb::points::TypedAttributeArray<openvdb::Vec3s,
|
||||
openvdb::points::TruncateCodec>::registerType();
|
||||
}
|
||||
|
||||
int writeObjectsVDB(const string &filename,
|
||||
std::vector<PbClass *> *objects,
|
||||
float worldSize,
|
||||
bool skipDeletedParts,
|
||||
int compression,
|
||||
int precision,
|
||||
float clip,
|
||||
const Grid<Real> *clipGrid,
|
||||
const bool meta)
|
||||
{
|
||||
openvdb::initialize();
|
||||
openvdb::io::File file(filename);
|
||||
openvdb::GridPtrVec gridsVDB;
|
||||
|
||||
// Register custom codecs, this makes sure custom attributes can be read
|
||||
registerCustomCodecs();
|
||||
|
||||
std::vector<ParticleDataBase *> pdbBuffer;
|
||||
|
||||
// Convert given clip grid to vdb clip grid
|
||||
openvdb::FloatGrid::Ptr vdbClipGrid = nullptr;
|
||||
if (clipGrid) {
|
||||
vdbClipGrid = openvdb::FloatGrid::create();
|
||||
Real *data = (Real *)clipGrid->getData();
|
||||
openvdb::math::CoordBBox bbox(openvdb::Coord(0),
|
||||
openvdb::Coord(clipGrid->getSizeX() - 1,
|
||||
clipGrid->getSizeY() - 1,
|
||||
clipGrid->getSizeZ() - 1));
|
||||
openvdb::tools::Dense<float, openvdb::tools::MemoryLayout::LayoutXYZ> dense(bbox, data);
|
||||
openvdb::tools::copyFromDense(dense, *vdbClipGrid, clip);
|
||||
}
|
||||
|
||||
for (std::vector<PbClass *>::iterator iter = objects->begin(); iter != objects->end(); ++iter) {
|
||||
openvdb::GridClass gClass = openvdb::GRID_UNKNOWN;
|
||||
openvdb::GridBase::Ptr vdbGrid;
|
||||
|
||||
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;
|
||||
if (clipGrid && mantaIntGrid->saveSparse()) {
|
||||
assertMsg(clipGrid->getSize() == mantaGrid->getSize(),
|
||||
"writeObjectsVDB: Clip grid and exported grid must have the same size "
|
||||
<< clipGrid->getSize() << " vs " << mantaGrid->getSize());
|
||||
}
|
||||
vdbGrid = exportVDB<int, openvdb::Int32Grid>(mantaIntGrid, clip, vdbClipGrid);
|
||||
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;
|
||||
// Only supply clip grid if real grid is not equal to the clip grid
|
||||
openvdb::FloatGrid::Ptr tmpClipGrid = (mantaRealGrid == clipGrid) ? nullptr : vdbClipGrid;
|
||||
if (clipGrid && mantaRealGrid->saveSparse()) {
|
||||
assertMsg(clipGrid->getSize() == mantaGrid->getSize(),
|
||||
"writeObjectsVDB: Clip grid and exported grid must have the same size "
|
||||
<< clipGrid->getSize() << " vs " << mantaGrid->getSize());
|
||||
}
|
||||
vdbGrid = exportVDB<Real, openvdb::FloatGrid>(mantaRealGrid, clip, tmpClipGrid);
|
||||
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;
|
||||
if (clipGrid && mantaVec3Grid->saveSparse()) {
|
||||
assertMsg(clipGrid->getSize() == mantaGrid->getSize(),
|
||||
"writeObjectsVDB: Clip grid and exported grid must have the same size "
|
||||
<< clipGrid->getSize() << " vs " << mantaGrid->getSize());
|
||||
}
|
||||
vdbGrid = exportVDB<Vec3, openvdb::Vec3SGrid>(mantaVec3Grid, clip, vdbClipGrid);
|
||||
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, precision);
|
||||
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, 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));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 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 there 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;
|
||||
}
|
||||
default:
|
||||
case COMPRESSION_ZIP: {
|
||||
vdb_flags |= openvdb::io::COMPRESS_ZIP;
|
||||
break;
|
||||
}
|
||||
case COMPRESSION_BLOSC: {
|
||||
# if OPENVDB_BLOSC == 1
|
||||
// Cannot use |= here, causes segfault with blosc 1.5.0 (== recommended version)
|
||||
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;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
|
||||
openvdb::initialize();
|
||||
openvdb::io::File file(filename);
|
||||
openvdb::GridPtrVec gridsVDB;
|
||||
|
||||
// Register custom codecs, this makes sure custom attributes can be read
|
||||
registerCustomCodecs();
|
||||
|
||||
try {
|
||||
#ifdef OPENVDB_USE_DELAYED_LOADING
|
||||
file.setCopyMaxBytes(0);
|
||||
#endif
|
||||
file.open();
|
||||
gridsVDB = *(file.getGrids());
|
||||
openvdb::MetaMap::Ptr metadata = file.getMetadata();
|
||||
unusedParameter(metadata); // Unused for now
|
||||
}
|
||||
catch (const openvdb::IoError &e) {
|
||||
unusedParameter(e); // Unused for now
|
||||
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;
|
||||
|
||||
// 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()) {
|
||||
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).
|
||||
const bool onlyGrid = (gridsVDB.size() == 1);
|
||||
|
||||
PbClass *object = dynamic_cast<PbClass *>(*iter);
|
||||
const Real dx = object->getParent()->getDx();
|
||||
const Vec3i origRes = object->getParent()->getGridSize();
|
||||
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;
|
||||
}
|
||||
|
||||
// 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) {
|
||||
openvdb::Int32Grid::Ptr vdbIntGrid = openvdb::gridPtrCast<openvdb::Int32Grid>(vdbGrid);
|
||||
if (!vdbIntGrid)
|
||||
continue; // Sanity check: Cast can fail if onlyGrid is true but object count > 1
|
||||
|
||||
Grid<int> *mantaIntGrid = (Grid<int> *)mantaGrid;
|
||||
debMsg("Reading into grid '" << mantaGrid->getName() << "' from int grid '"
|
||||
<< vdbGrid->getName() << "' in vdb file " << filename,
|
||||
1);
|
||||
importVDB<openvdb::Int32Grid, int>(vdbIntGrid, mantaIntGrid);
|
||||
}
|
||||
else if (mantaGrid->getType() & GridBase::TypeReal) {
|
||||
openvdb::FloatGrid::Ptr vdbFloatGrid = openvdb::gridPtrCast<openvdb::FloatGrid>(vdbGrid);
|
||||
if (!vdbFloatGrid)
|
||||
continue; // Sanity check: Cast can fail if onlyGrid is true but object count > 1
|
||||
|
||||
Grid<Real> *mantaRealGrid = (Grid<Real> *)mantaGrid;
|
||||
debMsg("Reading into grid '" << mantaGrid->getName() << "' from real grid '"
|
||||
<< vdbGrid->getName() << "' in vdb file " << filename,
|
||||
1);
|
||||
importVDB<openvdb::FloatGrid, Real>(vdbFloatGrid, mantaRealGrid);
|
||||
}
|
||||
else if (mantaGrid->getType() & GridBase::TypeVec3) {
|
||||
openvdb::Vec3SGrid::Ptr vdbVec3Grid = openvdb::gridPtrCast<openvdb::Vec3SGrid>(vdbGrid);
|
||||
if (!vdbVec3Grid)
|
||||
continue; // Sanity check: Cast can fail if onlyGrid is true but object count > 1
|
||||
|
||||
Grid<Vec3> *mantaVec3Grid = (Grid<Vec3> *)mantaGrid;
|
||||
debMsg("Reading into grid '" << mantaGrid->getName() << "' from vec3 grid '"
|
||||
<< vdbGrid->getName() << "' in vdb file " << filename,
|
||||
1);
|
||||
importVDB<openvdb::Vec3SGrid, Vec3>(vdbVec3Grid, mantaVec3Grid);
|
||||
}
|
||||
else {
|
||||
errMsg("readObjectsVDB: unknown grid type");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
else if (BasicParticleSystem *mantaPP = dynamic_cast<BasicParticleSystem *>(*iter)) {
|
||||
openvdb::points::PointDataGrid::Ptr vdbPointGrid =
|
||||
openvdb::gridPtrCast<openvdb::points::PointDataGrid>(vdbGrid);
|
||||
if (!vdbPointGrid)
|
||||
continue; // Sanity check: Cast can fail if onlyGrid is true but objects > 1
|
||||
|
||||
debMsg("Reading into particle system '" << mantaPP->getName() << "' from particle system '"
|
||||
<< vdbGrid->getName() << "' in vdb file "
|
||||
<< filename,
|
||||
1);
|
||||
importVDB(vdbPointGrid, mantaPP, pdbBuffer, voxelSize);
|
||||
pdbBuffer.clear();
|
||||
}
|
||||
else {
|
||||
errMsg("readObjectsVDB: Unsupported Python object. Cannot read from .vdb file "
|
||||
<< filename);
|
||||
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
|
||||
// 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, float clip = 1e-4, openvdb::FloatGrid::Ptr clipGrid = nullptr);
|
||||
template openvdb::FloatGrid::Ptr exportVDB<Real, openvdb::FloatGrid>(
|
||||
Grid<Real> *from, float clip = 1e-4, openvdb::FloatGrid::Ptr clipGrid = nullptr);
|
||||
template openvdb::Vec3SGrid::Ptr exportVDB<Vec3, openvdb::Vec3SGrid>(
|
||||
Grid<Vec3> *from, float clip = 1e-4, openvdb::FloatGrid::Ptr clipGrid = nullptr);
|
||||
|
||||
openvdb::points::PointDataGrid::Ptr exportVDB(BasicParticleSystem *from,
|
||||
std::vector<ParticleDataBase *> &fromPData,
|
||||
bool skipDeletedParts = false,
|
||||
float voxelSize = 1.0,
|
||||
int precision = PRECISION_HALF);
|
||||
template void exportVDB<int, int>(ParticleDataImpl<int> *from,
|
||||
openvdb::points::PointDataGrid::Ptr to,
|
||||
openvdb::tools::PointIndexGrid::Ptr pIndex,
|
||||
bool skipDeletedParts = false,
|
||||
int precision = PRECISION_HALF);
|
||||
template void exportVDB<Real, float>(ParticleDataImpl<Real> *from,
|
||||
openvdb::points::PointDataGrid::Ptr to,
|
||||
openvdb::tools::PointIndexGrid::Ptr pIndex,
|
||||
bool skipDeletedParts = false,
|
||||
int precision = PRECISION_HALF);
|
||||
template void exportVDB<Vec3, openvdb::Vec3s>(ParticleDataImpl<Vec3> *from,
|
||||
openvdb::points::PointDataGrid::Ptr to,
|
||||
openvdb::tools::PointIndexGrid::Ptr pIndex,
|
||||
bool skipDeletedParts = false,
|
||||
int precision = PRECISION_HALF);
|
||||
|
||||
#else
|
||||
|
||||
int writeObjectsVDB(const string &filename,
|
||||
std::vector<PbClass *> *objects,
|
||||
float worldSize,
|
||||
bool skipDeletedParts,
|
||||
int compression,
|
||||
int precision,
|
||||
float clip,
|
||||
const Grid<Real> *clipGrid,
|
||||
const bool meta)
|
||||
{
|
||||
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
|
||||
167
blender-5.2.0/extern/mantaflow/preprocessed/fileio/mantaio.cpp
vendored
Normal file
167
blender-5.2.0/extern/mantaflow/preprocessed/fileio/mantaio.cpp
vendored
Normal file
@@ -0,0 +1,167 @@
|
||||
|
||||
|
||||
// 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 = nullptr;
|
||||
{
|
||||
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,
|
||||
int precision = PRECISION_HALF,
|
||||
float clip = 1e-4,
|
||||
const Grid<Real> *clipGrid = nullptr,
|
||||
const bool meta = false)
|
||||
{
|
||||
|
||||
if (!precisionHalf) {
|
||||
debMsg("Warning: precisionHalf argument is deprecated. Please use precision level instead", 0);
|
||||
precision = PRECISION_HALF; // for backwards compatibility
|
||||
}
|
||||
|
||||
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, precision, clip, clipGrid, meta);
|
||||
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 = nullptr;
|
||||
{
|
||||
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);
|
||||
int precision = _args.getOpt<int>("precision", 6, PRECISION_HALF, &_lock);
|
||||
float clip = _args.getOpt<float>("clip", 7, 1e-4, &_lock);
|
||||
const Grid<Real> *clipGrid = _args.getPtrOpt<Grid<Real>>("clipGrid", 8, nullptr, &_lock);
|
||||
const bool meta = _args.getOpt<bool>("meta", 9, false, &_lock);
|
||||
_retval = toPy(save(name,
|
||||
objects,
|
||||
worldSize,
|
||||
skipDeletedParts,
|
||||
compression,
|
||||
precisionHalf,
|
||||
precision,
|
||||
clip,
|
||||
clipGrid,
|
||||
meta));
|
||||
_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
|
||||
131
blender-5.2.0/extern/mantaflow/preprocessed/fileio/mantaio.h
vendored
Normal file
131
blender-5.2.0/extern/mantaflow/preprocessed/fileio/mantaio.h
vendored
Normal file
@@ -0,0 +1,131 @@
|
||||
|
||||
|
||||
// DO NOT EDIT !
|
||||
// This file is generated using the MantaFlow preprocessor (prep generate).
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* MantaFlow fluid solver framework
|
||||
* Copyright 2011 Tobias Pfaff, 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 meshes to disk
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
#ifndef _FILEIO_H
|
||||
#define _FILEIO_H
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "manta.h"
|
||||
|
||||
// OpenVDB compression flags
|
||||
#define COMPRESSION_NONE 0
|
||||
#define COMPRESSION_ZIP 1
|
||||
#define COMPRESSION_BLOSC 2
|
||||
|
||||
// OpenVDB precision flags
|
||||
#define PRECISION_FULL 0
|
||||
#define PRECISION_HALF 1
|
||||
#define PRECISION_MINI 2
|
||||
|
||||
namespace Manta {
|
||||
|
||||
// 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;
|
||||
|
||||
// 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,
|
||||
int precision = PRECISION_HALF,
|
||||
float clip = 1e-4,
|
||||
const Grid<Real> *clipGrid = nullptr,
|
||||
const bool meta = false);
|
||||
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>
|
||||
int readGrid4dUni(const std::string &name,
|
||||
Grid4d<T> *grid,
|
||||
int readTslice = -1,
|
||||
Grid4d<T> *slice = nullptr,
|
||||
void **fileHandle = nullptr);
|
||||
void readGrid4dUniCleanup(void **fileHandle);
|
||||
template<class T> int writeGrid4dRaw(const std::string &name, Grid4d<T> *grid);
|
||||
template<class T> int readGrid4dRaw(const std::string &name, Grid4d<T> *grid);
|
||||
|
||||
// Particles + particle data
|
||||
int writeParticlesUni(const std::string &name, const BasicParticleSystem *parts);
|
||||
int readParticlesUni(const std::string &name, BasicParticleSystem *parts);
|
||||
|
||||
template<class T> int writePdataUni(const std::string &name, ParticleDataImpl<T> *pdata);
|
||||
template<class T> int readPdataUni(const std::string &name, ParticleDataImpl<T> *pdata);
|
||||
|
||||
// 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 = nullptr,
|
||||
std::string *info = nullptr);
|
||||
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
|
||||
|
||||
#endif
|
||||
13
blender-5.2.0/extern/mantaflow/preprocessed/fileio/mantaio.h.reg.cpp
vendored
Normal file
13
blender-5.2.0/extern/mantaflow/preprocessed/fileio/mantaio.h.reg.cpp
vendored
Normal file
@@ -0,0 +1,13 @@
|
||||
|
||||
|
||||
// DO NOT EDIT !
|
||||
// This file is generated using the MantaFlow preprocessor (prep link).
|
||||
|
||||
#include "fileio/mantaio.h"
|
||||
namespace Manta {
|
||||
extern "C" {
|
||||
void PbRegister_file_18()
|
||||
{
|
||||
}
|
||||
}
|
||||
} // namespace Manta
|
||||
Reference in New Issue
Block a user