Includes preprocessed Mantaflow source files for both OpenMP and TBB (if OpenMP is not present, TBB files will be used instead). These files come directly from the Mantaflow repository. Future updates to the core fluid solver will take place by updating the files. Reviewed By: sergey, mont29 Maniphest Tasks: T59995 Differential Revision: https://developer.blender.org/D3850
1691 lines
50 KiB
C++
1691 lines
50 KiB
C++
|
|
|
|
// 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
|
|
*
|
|
* Meshes
|
|
*
|
|
* note: this is only a temporary solution, details are bound to change
|
|
* long term goal is integration with Split&Merge code by Wojtan et al.
|
|
*
|
|
******************************************************************************/
|
|
|
|
#ifndef _MESH_H
|
|
#define _MESH_H
|
|
|
|
#include <vector>
|
|
#include "manta.h"
|
|
#include "vectorbase.h"
|
|
#include <set>
|
|
#include "levelset.h"
|
|
|
|
namespace Manta {
|
|
|
|
// fwd decl
|
|
class GridBase;
|
|
// class LevelsetGrid;
|
|
class FlagGrid;
|
|
class MACGrid;
|
|
class Shape;
|
|
class MeshDataBase;
|
|
template<class T> class MeshDataImpl;
|
|
|
|
//! Node position and flags
|
|
struct Node {
|
|
Node() : flags(0), pos(Vec3::Zero), normal(Vec3::Zero)
|
|
{
|
|
}
|
|
Node(const Vec3 &p) : flags(0), pos(p)
|
|
{
|
|
}
|
|
int flags;
|
|
Vec3 pos, normal;
|
|
};
|
|
|
|
//! Carries indices of its nodes
|
|
struct Triangle {
|
|
Triangle() : flags(0)
|
|
{
|
|
c[0] = c[1] = c[2] = 0;
|
|
}
|
|
Triangle(int n0, int n1, int n2) : flags(0)
|
|
{
|
|
c[0] = n0;
|
|
c[1] = n1;
|
|
c[2] = n2;
|
|
}
|
|
|
|
int c[3];
|
|
int flags;
|
|
};
|
|
|
|
//! For fast access to nodes and neighboring triangles
|
|
struct Corner {
|
|
Corner() : tri(-1), node(-1), opposite(-1), next(-1), prev(-1){};
|
|
Corner(int t, int n) : tri(t), node(n), opposite(-1), next(-1), prev(-1)
|
|
{
|
|
}
|
|
|
|
int tri;
|
|
int node;
|
|
int opposite;
|
|
int next;
|
|
int prev;
|
|
};
|
|
|
|
//! Base class for mesh data channels (texture coords, vorticity, ...)
|
|
struct NodeChannel {
|
|
virtual ~NodeChannel(){};
|
|
virtual void resize(int num) = 0;
|
|
virtual int size() = 0;
|
|
virtual NodeChannel *clone() = 0;
|
|
|
|
virtual void addInterpol(int a, int b, Real alpha) = 0;
|
|
virtual void mergeWith(int node, int delnode, Real alpha) = 0;
|
|
virtual void renumber(const std::vector<int> &newIndex, int newsize) = 0;
|
|
};
|
|
|
|
//! Node channel using only a vector
|
|
template<class T> struct SimpleNodeChannel : public NodeChannel {
|
|
SimpleNodeChannel(){};
|
|
SimpleNodeChannel(const SimpleNodeChannel<T> &a) : data(a.data)
|
|
{
|
|
}
|
|
void resize(int num)
|
|
{
|
|
data.resize(num);
|
|
}
|
|
virtual int size()
|
|
{
|
|
return data.size();
|
|
}
|
|
virtual void renumber(const std::vector<int> &newIndex, int newsize);
|
|
|
|
// virtual void addSplit(int from, Real alpha) { data.push_back(data[from]); }
|
|
|
|
std::vector<T> data;
|
|
};
|
|
|
|
//! Base class for mesh data channels (texture coords, vorticity, ...)
|
|
struct TriChannel {
|
|
virtual ~TriChannel(){};
|
|
virtual void resize(int num) = 0;
|
|
virtual TriChannel *clone() = 0;
|
|
virtual int size() = 0;
|
|
|
|
virtual void addNew() = 0;
|
|
virtual void addSplit(int from, Real alpha) = 0;
|
|
virtual void remove(int tri) = 0;
|
|
};
|
|
|
|
//! Tri channel using only a vector
|
|
template<class T> struct SimpleTriChannel : public TriChannel {
|
|
SimpleTriChannel(){};
|
|
SimpleTriChannel(const SimpleTriChannel<T> &a) : data(a.data)
|
|
{
|
|
}
|
|
void resize(int num)
|
|
{
|
|
data.resize(num);
|
|
}
|
|
void remove(int tri)
|
|
{
|
|
if (tri != (int)data.size() - 1)
|
|
data[tri] = *data.rbegin();
|
|
data.pop_back();
|
|
}
|
|
virtual int size()
|
|
{
|
|
return data.size();
|
|
}
|
|
|
|
virtual void addSplit(int from, Real alpha)
|
|
{
|
|
data.push_back(data[from]);
|
|
}
|
|
virtual void addNew()
|
|
{
|
|
data.push_back(T());
|
|
}
|
|
|
|
std::vector<T> data;
|
|
};
|
|
|
|
struct OneRing {
|
|
OneRing()
|
|
{
|
|
}
|
|
std::set<int> nodes;
|
|
std::set<int> tris;
|
|
};
|
|
|
|
//! Triangle mesh class
|
|
/*! note: this is only a temporary solution, details are bound to change
|
|
long term goal is integration with Split&Merge code by Wojtan et al.*/
|
|
class Mesh : public PbClass {
|
|
public:
|
|
Mesh(FluidSolver *parent);
|
|
static int _W_0(PyObject *_self, PyObject *_linargs, PyObject *_kwds)
|
|
{
|
|
PbClass *obj = Pb::objFromPy(_self);
|
|
if (obj)
|
|
delete obj;
|
|
try {
|
|
PbArgs _args(_linargs, _kwds);
|
|
bool noTiming = _args.getOpt<bool>("notiming", -1, 0);
|
|
pbPreparePlugin(0, "Mesh::Mesh", !noTiming);
|
|
{
|
|
ArgLocker _lock;
|
|
FluidSolver *parent = _args.getPtr<FluidSolver>("parent", 0, &_lock);
|
|
obj = new Mesh(parent);
|
|
obj->registerObject(_self, &_args);
|
|
_args.check();
|
|
}
|
|
pbFinalizePlugin(obj->getParent(), "Mesh::Mesh", !noTiming);
|
|
return 0;
|
|
}
|
|
catch (std::exception &e) {
|
|
pbSetError("Mesh::Mesh", e.what());
|
|
return -1;
|
|
}
|
|
}
|
|
|
|
virtual ~Mesh();
|
|
virtual Mesh *clone();
|
|
|
|
enum NodeFlags { NfNone = 0, NfFixed = 1, NfMarked = 2, NfKillme = 4, NfCollide = 8 };
|
|
enum FaceFlags { FfNone = 0, FfDoubled = 1, FfMarked = 2 };
|
|
enum MeshType { TypeNormal = 0, TypeVortexSheet };
|
|
|
|
virtual MeshType getType()
|
|
{
|
|
return TypeNormal;
|
|
}
|
|
|
|
Real computeCenterOfMass(Vec3 &cm) const;
|
|
void computeVertexNormals();
|
|
|
|
// plugins
|
|
void clear();
|
|
static PyObject *_W_1(PyObject *_self, PyObject *_linargs, PyObject *_kwds)
|
|
{
|
|
try {
|
|
PbArgs _args(_linargs, _kwds);
|
|
Mesh *pbo = dynamic_cast<Mesh *>(Pb::objFromPy(_self));
|
|
bool noTiming = _args.getOpt<bool>("notiming", -1, 0);
|
|
pbPreparePlugin(pbo->getParent(), "Mesh::clear", !noTiming);
|
|
PyObject *_retval = 0;
|
|
{
|
|
ArgLocker _lock;
|
|
pbo->_args.copy(_args);
|
|
_retval = getPyNone();
|
|
pbo->clear();
|
|
pbo->_args.check();
|
|
}
|
|
pbFinalizePlugin(pbo->getParent(), "Mesh::clear", !noTiming);
|
|
return _retval;
|
|
}
|
|
catch (std::exception &e) {
|
|
pbSetError("Mesh::clear", e.what());
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
void load(std::string name, bool append = false);
|
|
static PyObject *_W_2(PyObject *_self, PyObject *_linargs, PyObject *_kwds)
|
|
{
|
|
try {
|
|
PbArgs _args(_linargs, _kwds);
|
|
Mesh *pbo = dynamic_cast<Mesh *>(Pb::objFromPy(_self));
|
|
bool noTiming = _args.getOpt<bool>("notiming", -1, 0);
|
|
pbPreparePlugin(pbo->getParent(), "Mesh::load", !noTiming);
|
|
PyObject *_retval = 0;
|
|
{
|
|
ArgLocker _lock;
|
|
std::string name = _args.get<std::string>("name", 0, &_lock);
|
|
bool append = _args.getOpt<bool>("append", 1, false, &_lock);
|
|
pbo->_args.copy(_args);
|
|
_retval = getPyNone();
|
|
pbo->load(name, append);
|
|
pbo->_args.check();
|
|
}
|
|
pbFinalizePlugin(pbo->getParent(), "Mesh::load", !noTiming);
|
|
return _retval;
|
|
}
|
|
catch (std::exception &e) {
|
|
pbSetError("Mesh::load", e.what());
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
void fromShape(Shape &shape, bool append = false);
|
|
static PyObject *_W_3(PyObject *_self, PyObject *_linargs, PyObject *_kwds)
|
|
{
|
|
try {
|
|
PbArgs _args(_linargs, _kwds);
|
|
Mesh *pbo = dynamic_cast<Mesh *>(Pb::objFromPy(_self));
|
|
bool noTiming = _args.getOpt<bool>("notiming", -1, 0);
|
|
pbPreparePlugin(pbo->getParent(), "Mesh::fromShape", !noTiming);
|
|
PyObject *_retval = 0;
|
|
{
|
|
ArgLocker _lock;
|
|
Shape &shape = *_args.getPtr<Shape>("shape", 0, &_lock);
|
|
bool append = _args.getOpt<bool>("append", 1, false, &_lock);
|
|
pbo->_args.copy(_args);
|
|
_retval = getPyNone();
|
|
pbo->fromShape(shape, append);
|
|
pbo->_args.check();
|
|
}
|
|
pbFinalizePlugin(pbo->getParent(), "Mesh::fromShape", !noTiming);
|
|
return _retval;
|
|
}
|
|
catch (std::exception &e) {
|
|
pbSetError("Mesh::fromShape", e.what());
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
void save(std::string name);
|
|
static PyObject *_W_4(PyObject *_self, PyObject *_linargs, PyObject *_kwds)
|
|
{
|
|
try {
|
|
PbArgs _args(_linargs, _kwds);
|
|
Mesh *pbo = dynamic_cast<Mesh *>(Pb::objFromPy(_self));
|
|
bool noTiming = _args.getOpt<bool>("notiming", -1, 0);
|
|
pbPreparePlugin(pbo->getParent(), "Mesh::save", !noTiming);
|
|
PyObject *_retval = 0;
|
|
{
|
|
ArgLocker _lock;
|
|
std::string name = _args.get<std::string>("name", 0, &_lock);
|
|
pbo->_args.copy(_args);
|
|
_retval = getPyNone();
|
|
pbo->save(name);
|
|
pbo->_args.check();
|
|
}
|
|
pbFinalizePlugin(pbo->getParent(), "Mesh::save", !noTiming);
|
|
return _retval;
|
|
}
|
|
catch (std::exception &e) {
|
|
pbSetError("Mesh::save", e.what());
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
void advectInGrid(FlagGrid &flags, MACGrid &vel, int integrationMode);
|
|
static PyObject *_W_5(PyObject *_self, PyObject *_linargs, PyObject *_kwds)
|
|
{
|
|
try {
|
|
PbArgs _args(_linargs, _kwds);
|
|
Mesh *pbo = dynamic_cast<Mesh *>(Pb::objFromPy(_self));
|
|
bool noTiming = _args.getOpt<bool>("notiming", -1, 0);
|
|
pbPreparePlugin(pbo->getParent(), "Mesh::advectInGrid", !noTiming);
|
|
PyObject *_retval = 0;
|
|
{
|
|
ArgLocker _lock;
|
|
FlagGrid &flags = *_args.getPtr<FlagGrid>("flags", 0, &_lock);
|
|
MACGrid &vel = *_args.getPtr<MACGrid>("vel", 1, &_lock);
|
|
int integrationMode = _args.get<int>("integrationMode", 2, &_lock);
|
|
pbo->_args.copy(_args);
|
|
_retval = getPyNone();
|
|
pbo->advectInGrid(flags, vel, integrationMode);
|
|
pbo->_args.check();
|
|
}
|
|
pbFinalizePlugin(pbo->getParent(), "Mesh::advectInGrid", !noTiming);
|
|
return _retval;
|
|
}
|
|
catch (std::exception &e) {
|
|
pbSetError("Mesh::advectInGrid", e.what());
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
void scale(Vec3 s);
|
|
static PyObject *_W_6(PyObject *_self, PyObject *_linargs, PyObject *_kwds)
|
|
{
|
|
try {
|
|
PbArgs _args(_linargs, _kwds);
|
|
Mesh *pbo = dynamic_cast<Mesh *>(Pb::objFromPy(_self));
|
|
bool noTiming = _args.getOpt<bool>("notiming", -1, 0);
|
|
pbPreparePlugin(pbo->getParent(), "Mesh::scale", !noTiming);
|
|
PyObject *_retval = 0;
|
|
{
|
|
ArgLocker _lock;
|
|
Vec3 s = _args.get<Vec3>("s", 0, &_lock);
|
|
pbo->_args.copy(_args);
|
|
_retval = getPyNone();
|
|
pbo->scale(s);
|
|
pbo->_args.check();
|
|
}
|
|
pbFinalizePlugin(pbo->getParent(), "Mesh::scale", !noTiming);
|
|
return _retval;
|
|
}
|
|
catch (std::exception &e) {
|
|
pbSetError("Mesh::scale", e.what());
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
void offset(Vec3 o);
|
|
static PyObject *_W_7(PyObject *_self, PyObject *_linargs, PyObject *_kwds)
|
|
{
|
|
try {
|
|
PbArgs _args(_linargs, _kwds);
|
|
Mesh *pbo = dynamic_cast<Mesh *>(Pb::objFromPy(_self));
|
|
bool noTiming = _args.getOpt<bool>("notiming", -1, 0);
|
|
pbPreparePlugin(pbo->getParent(), "Mesh::offset", !noTiming);
|
|
PyObject *_retval = 0;
|
|
{
|
|
ArgLocker _lock;
|
|
Vec3 o = _args.get<Vec3>("o", 0, &_lock);
|
|
pbo->_args.copy(_args);
|
|
_retval = getPyNone();
|
|
pbo->offset(o);
|
|
pbo->_args.check();
|
|
}
|
|
pbFinalizePlugin(pbo->getParent(), "Mesh::offset", !noTiming);
|
|
return _retval;
|
|
}
|
|
catch (std::exception &e) {
|
|
pbSetError("Mesh::offset", e.what());
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
void rotate(Vec3 thetas);
|
|
static PyObject *_W_8(PyObject *_self, PyObject *_linargs, PyObject *_kwds)
|
|
{
|
|
try {
|
|
PbArgs _args(_linargs, _kwds);
|
|
Mesh *pbo = dynamic_cast<Mesh *>(Pb::objFromPy(_self));
|
|
bool noTiming = _args.getOpt<bool>("notiming", -1, 0);
|
|
pbPreparePlugin(pbo->getParent(), "Mesh::rotate", !noTiming);
|
|
PyObject *_retval = 0;
|
|
{
|
|
ArgLocker _lock;
|
|
Vec3 thetas = _args.get<Vec3>("thetas", 0, &_lock);
|
|
pbo->_args.copy(_args);
|
|
_retval = getPyNone();
|
|
pbo->rotate(thetas);
|
|
pbo->_args.check();
|
|
}
|
|
pbFinalizePlugin(pbo->getParent(), "Mesh::rotate", !noTiming);
|
|
return _retval;
|
|
}
|
|
catch (std::exception &e) {
|
|
pbSetError("Mesh::rotate", e.what());
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
void computeVelocity(Mesh &oldMesh, MACGrid &vel);
|
|
static PyObject *_W_9(PyObject *_self, PyObject *_linargs, PyObject *_kwds)
|
|
{
|
|
try {
|
|
PbArgs _args(_linargs, _kwds);
|
|
Mesh *pbo = dynamic_cast<Mesh *>(Pb::objFromPy(_self));
|
|
bool noTiming = _args.getOpt<bool>("notiming", -1, 0);
|
|
pbPreparePlugin(pbo->getParent(), "Mesh::computeVelocity", !noTiming);
|
|
PyObject *_retval = 0;
|
|
{
|
|
ArgLocker _lock;
|
|
Mesh &oldMesh = *_args.getPtr<Mesh>("oldMesh", 0, &_lock);
|
|
MACGrid &vel = *_args.getPtr<MACGrid>("vel", 1, &_lock);
|
|
pbo->_args.copy(_args);
|
|
_retval = getPyNone();
|
|
pbo->computeVelocity(oldMesh, vel);
|
|
pbo->_args.check();
|
|
}
|
|
pbFinalizePlugin(pbo->getParent(), "Mesh::computeVelocity", !noTiming);
|
|
return _retval;
|
|
}
|
|
catch (std::exception &e) {
|
|
pbSetError("Mesh::computeVelocity", e.what());
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
void computeLevelset(LevelsetGrid &levelset, Real sigma, Real cutoff = -1.);
|
|
static PyObject *_W_10(PyObject *_self, PyObject *_linargs, PyObject *_kwds)
|
|
{
|
|
try {
|
|
PbArgs _args(_linargs, _kwds);
|
|
Mesh *pbo = dynamic_cast<Mesh *>(Pb::objFromPy(_self));
|
|
bool noTiming = _args.getOpt<bool>("notiming", -1, 0);
|
|
pbPreparePlugin(pbo->getParent(), "Mesh::computeLevelset", !noTiming);
|
|
PyObject *_retval = 0;
|
|
{
|
|
ArgLocker _lock;
|
|
LevelsetGrid &levelset = *_args.getPtr<LevelsetGrid>("levelset", 0, &_lock);
|
|
Real sigma = _args.get<Real>("sigma", 1, &_lock);
|
|
Real cutoff = _args.getOpt<Real>("cutoff", 2, -1., &_lock);
|
|
pbo->_args.copy(_args);
|
|
_retval = getPyNone();
|
|
pbo->computeLevelset(levelset, sigma, cutoff);
|
|
pbo->_args.check();
|
|
}
|
|
pbFinalizePlugin(pbo->getParent(), "Mesh::computeLevelset", !noTiming);
|
|
return _retval;
|
|
}
|
|
catch (std::exception &e) {
|
|
pbSetError("Mesh::computeLevelset", e.what());
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
LevelsetGrid getLevelset(Real sigma, Real cutoff = -1.);
|
|
static PyObject *_W_11(PyObject *_self, PyObject *_linargs, PyObject *_kwds)
|
|
{
|
|
try {
|
|
PbArgs _args(_linargs, _kwds);
|
|
Mesh *pbo = dynamic_cast<Mesh *>(Pb::objFromPy(_self));
|
|
bool noTiming = _args.getOpt<bool>("notiming", -1, 0);
|
|
pbPreparePlugin(pbo->getParent(), "Mesh::getLevelset", !noTiming);
|
|
PyObject *_retval = 0;
|
|
{
|
|
ArgLocker _lock;
|
|
Real sigma = _args.get<Real>("sigma", 0, &_lock);
|
|
Real cutoff = _args.getOpt<Real>("cutoff", 1, -1., &_lock);
|
|
pbo->_args.copy(_args);
|
|
_retval = toPy(pbo->getLevelset(sigma, cutoff));
|
|
pbo->_args.check();
|
|
}
|
|
pbFinalizePlugin(pbo->getParent(), "Mesh::getLevelset", !noTiming);
|
|
return _retval;
|
|
}
|
|
catch (std::exception &e) {
|
|
pbSetError("Mesh::getLevelset", e.what());
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
//! map mesh to grid with sdf
|
|
void applyMeshToGrid(GridBase *grid,
|
|
FlagGrid *respectFlags = 0,
|
|
Real cutoff = -1.,
|
|
Real meshSigma = 2.);
|
|
static PyObject *_W_12(PyObject *_self, PyObject *_linargs, PyObject *_kwds)
|
|
{
|
|
try {
|
|
PbArgs _args(_linargs, _kwds);
|
|
Mesh *pbo = dynamic_cast<Mesh *>(Pb::objFromPy(_self));
|
|
bool noTiming = _args.getOpt<bool>("notiming", -1, 0);
|
|
pbPreparePlugin(pbo->getParent(), "Mesh::applyMeshToGrid", !noTiming);
|
|
PyObject *_retval = 0;
|
|
{
|
|
ArgLocker _lock;
|
|
GridBase *grid = _args.getPtr<GridBase>("grid", 0, &_lock);
|
|
FlagGrid *respectFlags = _args.getPtrOpt<FlagGrid>("respectFlags", 1, 0, &_lock);
|
|
Real cutoff = _args.getOpt<Real>("cutoff", 2, -1., &_lock);
|
|
Real meshSigma = _args.getOpt<Real>("meshSigma", 3, 2., &_lock);
|
|
pbo->_args.copy(_args);
|
|
_retval = getPyNone();
|
|
pbo->applyMeshToGrid(grid, respectFlags, cutoff, meshSigma);
|
|
pbo->_args.check();
|
|
}
|
|
pbFinalizePlugin(pbo->getParent(), "Mesh::applyMeshToGrid", !noTiming);
|
|
return _retval;
|
|
}
|
|
catch (std::exception &e) {
|
|
pbSetError("Mesh::applyMeshToGrid", e.what());
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
//! get data pointer of nodes
|
|
std::string getNodesDataPointer();
|
|
static PyObject *_W_13(PyObject *_self, PyObject *_linargs, PyObject *_kwds)
|
|
{
|
|
try {
|
|
PbArgs _args(_linargs, _kwds);
|
|
Mesh *pbo = dynamic_cast<Mesh *>(Pb::objFromPy(_self));
|
|
bool noTiming = _args.getOpt<bool>("notiming", -1, 0);
|
|
pbPreparePlugin(pbo->getParent(), "Mesh::getNodesDataPointer", !noTiming);
|
|
PyObject *_retval = 0;
|
|
{
|
|
ArgLocker _lock;
|
|
pbo->_args.copy(_args);
|
|
_retval = toPy(pbo->getNodesDataPointer());
|
|
pbo->_args.check();
|
|
}
|
|
pbFinalizePlugin(pbo->getParent(), "Mesh::getNodesDataPointer", !noTiming);
|
|
return _retval;
|
|
}
|
|
catch (std::exception &e) {
|
|
pbSetError("Mesh::getNodesDataPointer", e.what());
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
//! get data pointer of tris
|
|
std::string getTrisDataPointer();
|
|
static PyObject *_W_14(PyObject *_self, PyObject *_linargs, PyObject *_kwds)
|
|
{
|
|
try {
|
|
PbArgs _args(_linargs, _kwds);
|
|
Mesh *pbo = dynamic_cast<Mesh *>(Pb::objFromPy(_self));
|
|
bool noTiming = _args.getOpt<bool>("notiming", -1, 0);
|
|
pbPreparePlugin(pbo->getParent(), "Mesh::getTrisDataPointer", !noTiming);
|
|
PyObject *_retval = 0;
|
|
{
|
|
ArgLocker _lock;
|
|
pbo->_args.copy(_args);
|
|
_retval = toPy(pbo->getTrisDataPointer());
|
|
pbo->_args.check();
|
|
}
|
|
pbFinalizePlugin(pbo->getParent(), "Mesh::getTrisDataPointer", !noTiming);
|
|
return _retval;
|
|
}
|
|
catch (std::exception &e) {
|
|
pbSetError("Mesh::getTrisDataPointer", e.what());
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
// ops
|
|
Mesh &operator=(const Mesh &o);
|
|
|
|
// accessors
|
|
inline int numTris() const
|
|
{
|
|
return mTris.size();
|
|
}
|
|
inline int numNodes() const
|
|
{
|
|
return mNodes.size();
|
|
}
|
|
inline int numTriChannels() const
|
|
{
|
|
return mTriChannels.size();
|
|
}
|
|
inline int numNodeChannels() const
|
|
{
|
|
return mNodeChannels.size();
|
|
}
|
|
|
|
//! return size of container
|
|
//! note , python binding disabled for now! cannot yet deal with long-long types
|
|
inline IndexInt size() const
|
|
{
|
|
return mNodes.size();
|
|
}
|
|
//! slow virtual function of base class, also returns size
|
|
virtual IndexInt getSizeSlow() const
|
|
{
|
|
return size();
|
|
}
|
|
|
|
inline Triangle &tris(int i)
|
|
{
|
|
return mTris[i];
|
|
}
|
|
inline Node &nodes(int i)
|
|
{
|
|
return mNodes[i];
|
|
}
|
|
inline Corner &corners(int tri, int c)
|
|
{
|
|
return mCorners[tri * 3 + c];
|
|
}
|
|
inline Corner &corners(int c)
|
|
{
|
|
return mCorners[c];
|
|
}
|
|
inline NodeChannel *nodeChannel(int i)
|
|
{
|
|
return mNodeChannels[i];
|
|
}
|
|
inline TriChannel *triChannel(int i)
|
|
{
|
|
return mTriChannels[i];
|
|
}
|
|
|
|
// allocate memory (eg upon load)
|
|
void resizeTris(int numTris);
|
|
void resizeNodes(int numNodes);
|
|
|
|
inline bool isNodeFixed(int n)
|
|
{
|
|
return mNodes[n].flags & NfFixed;
|
|
}
|
|
inline bool isTriangleFixed(int t)
|
|
{
|
|
return (mNodes[mTris[t].c[0]].flags & NfFixed) || (mNodes[mTris[t].c[1]].flags & NfFixed) ||
|
|
(mNodes[mTris[t].c[2]].flags & NfFixed);
|
|
}
|
|
|
|
inline const Vec3 getNode(int tri, int c) const
|
|
{
|
|
return mNodes[mTris[tri].c[c]].pos;
|
|
}
|
|
inline Vec3 &getNode(int tri, int c)
|
|
{
|
|
return mNodes[mTris[tri].c[c]].pos;
|
|
}
|
|
inline const Vec3 getEdge(int tri, int e) const
|
|
{
|
|
return getNode(tri, (e + 1) % 3) - getNode(tri, e);
|
|
}
|
|
inline OneRing &get1Ring(int node)
|
|
{
|
|
return m1RingLookup[node];
|
|
}
|
|
inline Real getFaceArea(int t) const
|
|
{
|
|
Vec3 c0 = mNodes[mTris[t].c[0]].pos;
|
|
return 0.5 * norm(cross(mNodes[mTris[t].c[1]].pos - c0, mNodes[mTris[t].c[2]].pos - c0));
|
|
}
|
|
inline Vec3 getFaceNormal(int t)
|
|
{
|
|
Vec3 c0 = mNodes[mTris[t].c[0]].pos;
|
|
return getNormalized(cross(mNodes[mTris[t].c[1]].pos - c0, mNodes[mTris[t].c[2]].pos - c0));
|
|
}
|
|
inline Vec3 getFaceCenter(int t) const
|
|
{
|
|
return (mNodes[mTris[t].c[0]].pos + mNodes[mTris[t].c[1]].pos + mNodes[mTris[t].c[2]].pos) /
|
|
3.0;
|
|
}
|
|
inline std::vector<Node> &getNodeData()
|
|
{
|
|
return mNodes;
|
|
}
|
|
|
|
void mergeNode(int node, int delnode);
|
|
int addNode(Node a);
|
|
int addTri(Triangle a);
|
|
void addCorner(Corner a);
|
|
void removeTri(int tri);
|
|
void removeTriFromLookup(int tri);
|
|
void removeNodes(const std::vector<int> &deletedNodes);
|
|
void rebuildCorners(int from = 0, int to = -1);
|
|
void rebuildLookup(int from = 0, int to = -1);
|
|
void rebuildQuickCheck();
|
|
void fastNodeLookupRebuild(int corner);
|
|
void sanityCheck(bool strict = true,
|
|
std::vector<int> *deletedNodes = 0,
|
|
std::map<int, bool> *taintedTris = 0);
|
|
|
|
void addTriChannel(TriChannel *c)
|
|
{
|
|
mTriChannels.push_back(c);
|
|
rebuildChannels();
|
|
}
|
|
void addNodeChannel(NodeChannel *c)
|
|
{
|
|
mNodeChannels.push_back(c);
|
|
rebuildChannels();
|
|
}
|
|
|
|
//! mesh data functions
|
|
|
|
//! create a mesh data object
|
|
PbClass *create(PbType type, PbTypeVec T = PbTypeVec(), const std::string &name = "");
|
|
static PyObject *_W_15(PyObject *_self, PyObject *_linargs, PyObject *_kwds)
|
|
{
|
|
try {
|
|
PbArgs _args(_linargs, _kwds);
|
|
Mesh *pbo = dynamic_cast<Mesh *>(Pb::objFromPy(_self));
|
|
bool noTiming = _args.getOpt<bool>("notiming", -1, 0);
|
|
pbPreparePlugin(pbo->getParent(), "Mesh::create", !noTiming);
|
|
PyObject *_retval = 0;
|
|
{
|
|
ArgLocker _lock;
|
|
PbType type = _args.get<PbType>("type", 0, &_lock);
|
|
PbTypeVec T = _args.getOpt<PbTypeVec>("T", 1, PbTypeVec(), &_lock);
|
|
const std::string &name = _args.getOpt<std::string>("name", 2, "", &_lock);
|
|
pbo->_args.copy(_args);
|
|
_retval = toPy(pbo->create(type, T, name));
|
|
pbo->_args.check();
|
|
}
|
|
pbFinalizePlugin(pbo->getParent(), "Mesh::create", !noTiming);
|
|
return _retval;
|
|
}
|
|
catch (std::exception &e) {
|
|
pbSetError("Mesh::create", e.what());
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
//! add a mesh data field, set its parent mesh pointer
|
|
void registerMdata(MeshDataBase *mdata);
|
|
void registerMdataReal(MeshDataImpl<Real> *mdata);
|
|
void registerMdataVec3(MeshDataImpl<Vec3> *mdata);
|
|
void registerMdataInt(MeshDataImpl<int> *mdata);
|
|
//! remove a mesh data entry
|
|
void deregister(MeshDataBase *mdata);
|
|
//! add one zero entry to all data fields
|
|
void addAllMdata();
|
|
// note - deletion of mdata is handled in compress function
|
|
|
|
//! how many are there?
|
|
IndexInt getNumMdata() const
|
|
{
|
|
return mMeshData.size();
|
|
}
|
|
//! access one of the fields
|
|
MeshDataBase *getMdata(int i)
|
|
{
|
|
return mMeshData[i];
|
|
}
|
|
|
|
//! update data fields
|
|
void updateDataFields();
|
|
|
|
protected:
|
|
void rebuildChannels();
|
|
|
|
std::vector<Node> mNodes;
|
|
std::vector<Triangle> mTris;
|
|
std::vector<Corner> mCorners;
|
|
std::vector<NodeChannel *> mNodeChannels;
|
|
std::vector<TriChannel *> mTriChannels;
|
|
std::vector<OneRing> m1RingLookup;
|
|
|
|
//! store mesh data , each pointer has its own storage vector of a certain type (int, real, vec3)
|
|
std::vector<MeshDataBase *> mMeshData;
|
|
//! lists of different types, for fast operations w/o virtual function calls
|
|
std::vector<MeshDataImpl<Real> *> mMdataReal;
|
|
std::vector<MeshDataImpl<Vec3> *> mMdataVec3;
|
|
std::vector<MeshDataImpl<int> *>
|
|
mMdataInt; //! indicate that mdata of this mesh is copied, and needs to be freed
|
|
bool mFreeMdata;
|
|
public:
|
|
PbArgs _args;
|
|
}
|
|
#define _C_Mesh
|
|
;
|
|
|
|
//******************************************************************************
|
|
|
|
//! abstract interface for mesh data
|
|
class MeshDataBase : public PbClass {
|
|
public:
|
|
MeshDataBase(FluidSolver *parent);
|
|
static int _W_16(PyObject *_self, PyObject *_linargs, PyObject *_kwds)
|
|
{
|
|
PbClass *obj = Pb::objFromPy(_self);
|
|
if (obj)
|
|
delete obj;
|
|
try {
|
|
PbArgs _args(_linargs, _kwds);
|
|
bool noTiming = _args.getOpt<bool>("notiming", -1, 0);
|
|
pbPreparePlugin(0, "MeshDataBase::MeshDataBase", !noTiming);
|
|
{
|
|
ArgLocker _lock;
|
|
FluidSolver *parent = _args.getPtr<FluidSolver>("parent", 0, &_lock);
|
|
obj = new MeshDataBase(parent);
|
|
obj->registerObject(_self, &_args);
|
|
_args.check();
|
|
}
|
|
pbFinalizePlugin(obj->getParent(), "MeshDataBase::MeshDataBase", !noTiming);
|
|
return 0;
|
|
}
|
|
catch (std::exception &e) {
|
|
pbSetError("MeshDataBase::MeshDataBase", e.what());
|
|
return -1;
|
|
}
|
|
}
|
|
|
|
virtual ~MeshDataBase();
|
|
|
|
//! data type IDs, in line with those for grids
|
|
enum MdataType { TypeNone = 0, TypeReal = 1, TypeInt = 2, TypeVec3 = 4 };
|
|
|
|
//! interface functions, using assert instead of pure virtual for python compatibility
|
|
virtual IndexInt getSizeSlow() const
|
|
{
|
|
assertMsg(false, "Dont use, override...");
|
|
return 0;
|
|
}
|
|
virtual void addEntry()
|
|
{
|
|
assertMsg(false, "Dont use, override...");
|
|
return;
|
|
}
|
|
virtual MeshDataBase *clone()
|
|
{
|
|
assertMsg(false, "Dont use, override...");
|
|
return NULL;
|
|
}
|
|
virtual MdataType getType() const
|
|
{
|
|
assertMsg(false, "Dont use, override...");
|
|
return TypeNone;
|
|
}
|
|
virtual void resize(IndexInt size)
|
|
{
|
|
assertMsg(false, "Dont use, override...");
|
|
return;
|
|
}
|
|
virtual void copyValueSlow(IndexInt from, IndexInt to)
|
|
{
|
|
assertMsg(false, "Dont use, override...");
|
|
return;
|
|
}
|
|
|
|
//! set base pointer
|
|
void setMesh(Mesh *set)
|
|
{
|
|
mMesh = set;
|
|
}
|
|
|
|
//! debugging
|
|
inline void checkNodeIndex(IndexInt idx) const;
|
|
|
|
protected:
|
|
Mesh *mMesh;
|
|
public:
|
|
PbArgs _args;
|
|
}
|
|
#define _C_MeshDataBase
|
|
;
|
|
|
|
//! abstract interface for mesh data
|
|
|
|
template<class T> class MeshDataImpl : public MeshDataBase {
|
|
public:
|
|
MeshDataImpl(FluidSolver *parent);
|
|
static int _W_17(PyObject *_self, PyObject *_linargs, PyObject *_kwds)
|
|
{
|
|
PbClass *obj = Pb::objFromPy(_self);
|
|
if (obj)
|
|
delete obj;
|
|
try {
|
|
PbArgs _args(_linargs, _kwds);
|
|
bool noTiming = _args.getOpt<bool>("notiming", -1, 0);
|
|
pbPreparePlugin(0, "MeshDataImpl::MeshDataImpl", !noTiming);
|
|
{
|
|
ArgLocker _lock;
|
|
FluidSolver *parent = _args.getPtr<FluidSolver>("parent", 0, &_lock);
|
|
obj = new MeshDataImpl(parent);
|
|
obj->registerObject(_self, &_args);
|
|
_args.check();
|
|
}
|
|
pbFinalizePlugin(obj->getParent(), "MeshDataImpl::MeshDataImpl", !noTiming);
|
|
return 0;
|
|
}
|
|
catch (std::exception &e) {
|
|
pbSetError("MeshDataImpl::MeshDataImpl", e.what());
|
|
return -1;
|
|
}
|
|
}
|
|
|
|
MeshDataImpl(FluidSolver *parent, MeshDataImpl<T> *other);
|
|
virtual ~MeshDataImpl();
|
|
|
|
//! access data
|
|
inline T &get(IndexInt idx)
|
|
{
|
|
DEBUG_ONLY(checkNodeIndex(idx));
|
|
return mData[idx];
|
|
}
|
|
inline const T &get(IndexInt idx) const
|
|
{
|
|
DEBUG_ONLY(checkNodeIndex(idx));
|
|
return mData[idx];
|
|
}
|
|
inline T &operator[](IndexInt idx)
|
|
{
|
|
DEBUG_ONLY(checkNodeIndex(idx));
|
|
return mData[idx];
|
|
}
|
|
inline const T &operator[](IndexInt idx) const
|
|
{
|
|
DEBUG_ONLY(checkNodeIndex(idx));
|
|
return mData[idx];
|
|
}
|
|
|
|
//! set all values to 0, note - different from meshSystem::clear! doesnt modify size of array
|
|
//! (has to stay in sync with parent system)
|
|
void clear();
|
|
static PyObject *_W_18(PyObject *_self, PyObject *_linargs, PyObject *_kwds)
|
|
{
|
|
try {
|
|
PbArgs _args(_linargs, _kwds);
|
|
MeshDataImpl *pbo = dynamic_cast<MeshDataImpl *>(Pb::objFromPy(_self));
|
|
bool noTiming = _args.getOpt<bool>("notiming", -1, 0);
|
|
pbPreparePlugin(pbo->getParent(), "MeshDataImpl::clear", !noTiming);
|
|
PyObject *_retval = 0;
|
|
{
|
|
ArgLocker _lock;
|
|
pbo->_args.copy(_args);
|
|
_retval = getPyNone();
|
|
pbo->clear();
|
|
pbo->_args.check();
|
|
}
|
|
pbFinalizePlugin(pbo->getParent(), "MeshDataImpl::clear", !noTiming);
|
|
return _retval;
|
|
}
|
|
catch (std::exception &e) {
|
|
pbSetError("MeshDataImpl::clear", e.what());
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
//! set grid from which to get data...
|
|
void setSource(Grid<T> *grid, bool isMAC = false);
|
|
static PyObject *_W_19(PyObject *_self, PyObject *_linargs, PyObject *_kwds)
|
|
{
|
|
try {
|
|
PbArgs _args(_linargs, _kwds);
|
|
MeshDataImpl *pbo = dynamic_cast<MeshDataImpl *>(Pb::objFromPy(_self));
|
|
bool noTiming = _args.getOpt<bool>("notiming", -1, 0);
|
|
pbPreparePlugin(pbo->getParent(), "MeshDataImpl::setSource", !noTiming);
|
|
PyObject *_retval = 0;
|
|
{
|
|
ArgLocker _lock;
|
|
Grid<T> *grid = _args.getPtr<Grid<T>>("grid", 0, &_lock);
|
|
bool isMAC = _args.getOpt<bool>("isMAC", 1, false, &_lock);
|
|
pbo->_args.copy(_args);
|
|
_retval = getPyNone();
|
|
pbo->setSource(grid, isMAC);
|
|
pbo->_args.check();
|
|
}
|
|
pbFinalizePlugin(pbo->getParent(), "MeshDataImpl::setSource", !noTiming);
|
|
return _retval;
|
|
}
|
|
catch (std::exception &e) {
|
|
pbSetError("MeshDataImpl::setSource", e.what());
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
//! mesh data base interface
|
|
virtual IndexInt getSizeSlow() const;
|
|
virtual void addEntry();
|
|
virtual MeshDataBase *clone();
|
|
virtual MdataType getType() const;
|
|
virtual void resize(IndexInt s);
|
|
virtual void copyValueSlow(IndexInt from, IndexInt to);
|
|
|
|
IndexInt size() const
|
|
{
|
|
return mData.size();
|
|
}
|
|
|
|
//! fast inlined functions for per mesh operations
|
|
inline void copyValue(IndexInt from, IndexInt to)
|
|
{
|
|
get(to) = get(from);
|
|
}
|
|
void initNewValue(IndexInt idx, Vec3 pos);
|
|
|
|
//! python interface (similar to grid data)
|
|
void setConst(T s);
|
|
static PyObject *_W_20(PyObject *_self, PyObject *_linargs, PyObject *_kwds)
|
|
{
|
|
try {
|
|
PbArgs _args(_linargs, _kwds);
|
|
MeshDataImpl *pbo = dynamic_cast<MeshDataImpl *>(Pb::objFromPy(_self));
|
|
bool noTiming = _args.getOpt<bool>("notiming", -1, 0);
|
|
pbPreparePlugin(pbo->getParent(), "MeshDataImpl::setConst", !noTiming);
|
|
PyObject *_retval = 0;
|
|
{
|
|
ArgLocker _lock;
|
|
T s = _args.get<T>("s", 0, &_lock);
|
|
pbo->_args.copy(_args);
|
|
_retval = getPyNone();
|
|
pbo->setConst(s);
|
|
pbo->_args.check();
|
|
}
|
|
pbFinalizePlugin(pbo->getParent(), "MeshDataImpl::setConst", !noTiming);
|
|
return _retval;
|
|
}
|
|
catch (std::exception &e) {
|
|
pbSetError("MeshDataImpl::setConst", e.what());
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
void setConstRange(T s, const int begin, const int end);
|
|
static PyObject *_W_21(PyObject *_self, PyObject *_linargs, PyObject *_kwds)
|
|
{
|
|
try {
|
|
PbArgs _args(_linargs, _kwds);
|
|
MeshDataImpl *pbo = dynamic_cast<MeshDataImpl *>(Pb::objFromPy(_self));
|
|
bool noTiming = _args.getOpt<bool>("notiming", -1, 0);
|
|
pbPreparePlugin(pbo->getParent(), "MeshDataImpl::setConstRange", !noTiming);
|
|
PyObject *_retval = 0;
|
|
{
|
|
ArgLocker _lock;
|
|
T s = _args.get<T>("s", 0, &_lock);
|
|
const int begin = _args.get<int>("begin", 1, &_lock);
|
|
const int end = _args.get<int>("end", 2, &_lock);
|
|
pbo->_args.copy(_args);
|
|
_retval = getPyNone();
|
|
pbo->setConstRange(s, begin, end);
|
|
pbo->_args.check();
|
|
}
|
|
pbFinalizePlugin(pbo->getParent(), "MeshDataImpl::setConstRange", !noTiming);
|
|
return _retval;
|
|
}
|
|
catch (std::exception &e) {
|
|
pbSetError("MeshDataImpl::setConstRange", e.what());
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
MeshDataImpl<T> ©From(const MeshDataImpl<T> &a);
|
|
static PyObject *_W_22(PyObject *_self, PyObject *_linargs, PyObject *_kwds)
|
|
{
|
|
try {
|
|
PbArgs _args(_linargs, _kwds);
|
|
MeshDataImpl *pbo = dynamic_cast<MeshDataImpl *>(Pb::objFromPy(_self));
|
|
bool noTiming = _args.getOpt<bool>("notiming", -1, 0);
|
|
pbPreparePlugin(pbo->getParent(), "MeshDataImpl::copyFrom", !noTiming);
|
|
PyObject *_retval = 0;
|
|
{
|
|
ArgLocker _lock;
|
|
const MeshDataImpl<T> &a = *_args.getPtr<MeshDataImpl<T>>("a", 0, &_lock);
|
|
pbo->_args.copy(_args);
|
|
_retval = toPy(pbo->copyFrom(a));
|
|
pbo->_args.check();
|
|
}
|
|
pbFinalizePlugin(pbo->getParent(), "MeshDataImpl::copyFrom", !noTiming);
|
|
return _retval;
|
|
}
|
|
catch (std::exception &e) {
|
|
pbSetError("MeshDataImpl::copyFrom", e.what());
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
void add(const MeshDataImpl<T> &a);
|
|
static PyObject *_W_23(PyObject *_self, PyObject *_linargs, PyObject *_kwds)
|
|
{
|
|
try {
|
|
PbArgs _args(_linargs, _kwds);
|
|
MeshDataImpl *pbo = dynamic_cast<MeshDataImpl *>(Pb::objFromPy(_self));
|
|
bool noTiming = _args.getOpt<bool>("notiming", -1, 0);
|
|
pbPreparePlugin(pbo->getParent(), "MeshDataImpl::add", !noTiming);
|
|
PyObject *_retval = 0;
|
|
{
|
|
ArgLocker _lock;
|
|
const MeshDataImpl<T> &a = *_args.getPtr<MeshDataImpl<T>>("a", 0, &_lock);
|
|
pbo->_args.copy(_args);
|
|
_retval = getPyNone();
|
|
pbo->add(a);
|
|
pbo->_args.check();
|
|
}
|
|
pbFinalizePlugin(pbo->getParent(), "MeshDataImpl::add", !noTiming);
|
|
return _retval;
|
|
}
|
|
catch (std::exception &e) {
|
|
pbSetError("MeshDataImpl::add", e.what());
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
void sub(const MeshDataImpl<T> &a);
|
|
static PyObject *_W_24(PyObject *_self, PyObject *_linargs, PyObject *_kwds)
|
|
{
|
|
try {
|
|
PbArgs _args(_linargs, _kwds);
|
|
MeshDataImpl *pbo = dynamic_cast<MeshDataImpl *>(Pb::objFromPy(_self));
|
|
bool noTiming = _args.getOpt<bool>("notiming", -1, 0);
|
|
pbPreparePlugin(pbo->getParent(), "MeshDataImpl::sub", !noTiming);
|
|
PyObject *_retval = 0;
|
|
{
|
|
ArgLocker _lock;
|
|
const MeshDataImpl<T> &a = *_args.getPtr<MeshDataImpl<T>>("a", 0, &_lock);
|
|
pbo->_args.copy(_args);
|
|
_retval = getPyNone();
|
|
pbo->sub(a);
|
|
pbo->_args.check();
|
|
}
|
|
pbFinalizePlugin(pbo->getParent(), "MeshDataImpl::sub", !noTiming);
|
|
return _retval;
|
|
}
|
|
catch (std::exception &e) {
|
|
pbSetError("MeshDataImpl::sub", e.what());
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
void addConst(T s);
|
|
static PyObject *_W_25(PyObject *_self, PyObject *_linargs, PyObject *_kwds)
|
|
{
|
|
try {
|
|
PbArgs _args(_linargs, _kwds);
|
|
MeshDataImpl *pbo = dynamic_cast<MeshDataImpl *>(Pb::objFromPy(_self));
|
|
bool noTiming = _args.getOpt<bool>("notiming", -1, 0);
|
|
pbPreparePlugin(pbo->getParent(), "MeshDataImpl::addConst", !noTiming);
|
|
PyObject *_retval = 0;
|
|
{
|
|
ArgLocker _lock;
|
|
T s = _args.get<T>("s", 0, &_lock);
|
|
pbo->_args.copy(_args);
|
|
_retval = getPyNone();
|
|
pbo->addConst(s);
|
|
pbo->_args.check();
|
|
}
|
|
pbFinalizePlugin(pbo->getParent(), "MeshDataImpl::addConst", !noTiming);
|
|
return _retval;
|
|
}
|
|
catch (std::exception &e) {
|
|
pbSetError("MeshDataImpl::addConst", e.what());
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
void addScaled(const MeshDataImpl<T> &a, const T &factor);
|
|
static PyObject *_W_26(PyObject *_self, PyObject *_linargs, PyObject *_kwds)
|
|
{
|
|
try {
|
|
PbArgs _args(_linargs, _kwds);
|
|
MeshDataImpl *pbo = dynamic_cast<MeshDataImpl *>(Pb::objFromPy(_self));
|
|
bool noTiming = _args.getOpt<bool>("notiming", -1, 0);
|
|
pbPreparePlugin(pbo->getParent(), "MeshDataImpl::addScaled", !noTiming);
|
|
PyObject *_retval = 0;
|
|
{
|
|
ArgLocker _lock;
|
|
const MeshDataImpl<T> &a = *_args.getPtr<MeshDataImpl<T>>("a", 0, &_lock);
|
|
const T &factor = *_args.getPtr<T>("factor", 1, &_lock);
|
|
pbo->_args.copy(_args);
|
|
_retval = getPyNone();
|
|
pbo->addScaled(a, factor);
|
|
pbo->_args.check();
|
|
}
|
|
pbFinalizePlugin(pbo->getParent(), "MeshDataImpl::addScaled", !noTiming);
|
|
return _retval;
|
|
}
|
|
catch (std::exception &e) {
|
|
pbSetError("MeshDataImpl::addScaled", e.what());
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
void mult(const MeshDataImpl<T> &a);
|
|
static PyObject *_W_27(PyObject *_self, PyObject *_linargs, PyObject *_kwds)
|
|
{
|
|
try {
|
|
PbArgs _args(_linargs, _kwds);
|
|
MeshDataImpl *pbo = dynamic_cast<MeshDataImpl *>(Pb::objFromPy(_self));
|
|
bool noTiming = _args.getOpt<bool>("notiming", -1, 0);
|
|
pbPreparePlugin(pbo->getParent(), "MeshDataImpl::mult", !noTiming);
|
|
PyObject *_retval = 0;
|
|
{
|
|
ArgLocker _lock;
|
|
const MeshDataImpl<T> &a = *_args.getPtr<MeshDataImpl<T>>("a", 0, &_lock);
|
|
pbo->_args.copy(_args);
|
|
_retval = getPyNone();
|
|
pbo->mult(a);
|
|
pbo->_args.check();
|
|
}
|
|
pbFinalizePlugin(pbo->getParent(), "MeshDataImpl::mult", !noTiming);
|
|
return _retval;
|
|
}
|
|
catch (std::exception &e) {
|
|
pbSetError("MeshDataImpl::mult", e.what());
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
void multConst(T s);
|
|
static PyObject *_W_28(PyObject *_self, PyObject *_linargs, PyObject *_kwds)
|
|
{
|
|
try {
|
|
PbArgs _args(_linargs, _kwds);
|
|
MeshDataImpl *pbo = dynamic_cast<MeshDataImpl *>(Pb::objFromPy(_self));
|
|
bool noTiming = _args.getOpt<bool>("notiming", -1, 0);
|
|
pbPreparePlugin(pbo->getParent(), "MeshDataImpl::multConst", !noTiming);
|
|
PyObject *_retval = 0;
|
|
{
|
|
ArgLocker _lock;
|
|
T s = _args.get<T>("s", 0, &_lock);
|
|
pbo->_args.copy(_args);
|
|
_retval = getPyNone();
|
|
pbo->multConst(s);
|
|
pbo->_args.check();
|
|
}
|
|
pbFinalizePlugin(pbo->getParent(), "MeshDataImpl::multConst", !noTiming);
|
|
return _retval;
|
|
}
|
|
catch (std::exception &e) {
|
|
pbSetError("MeshDataImpl::multConst", e.what());
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
void safeDiv(const MeshDataImpl<T> &a);
|
|
static PyObject *_W_29(PyObject *_self, PyObject *_linargs, PyObject *_kwds)
|
|
{
|
|
try {
|
|
PbArgs _args(_linargs, _kwds);
|
|
MeshDataImpl *pbo = dynamic_cast<MeshDataImpl *>(Pb::objFromPy(_self));
|
|
bool noTiming = _args.getOpt<bool>("notiming", -1, 0);
|
|
pbPreparePlugin(pbo->getParent(), "MeshDataImpl::safeDiv", !noTiming);
|
|
PyObject *_retval = 0;
|
|
{
|
|
ArgLocker _lock;
|
|
const MeshDataImpl<T> &a = *_args.getPtr<MeshDataImpl<T>>("a", 0, &_lock);
|
|
pbo->_args.copy(_args);
|
|
_retval = getPyNone();
|
|
pbo->safeDiv(a);
|
|
pbo->_args.check();
|
|
}
|
|
pbFinalizePlugin(pbo->getParent(), "MeshDataImpl::safeDiv", !noTiming);
|
|
return _retval;
|
|
}
|
|
catch (std::exception &e) {
|
|
pbSetError("MeshDataImpl::safeDiv", e.what());
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
void clamp(Real min, Real max);
|
|
static PyObject *_W_30(PyObject *_self, PyObject *_linargs, PyObject *_kwds)
|
|
{
|
|
try {
|
|
PbArgs _args(_linargs, _kwds);
|
|
MeshDataImpl *pbo = dynamic_cast<MeshDataImpl *>(Pb::objFromPy(_self));
|
|
bool noTiming = _args.getOpt<bool>("notiming", -1, 0);
|
|
pbPreparePlugin(pbo->getParent(), "MeshDataImpl::clamp", !noTiming);
|
|
PyObject *_retval = 0;
|
|
{
|
|
ArgLocker _lock;
|
|
Real min = _args.get<Real>("min", 0, &_lock);
|
|
Real max = _args.get<Real>("max", 1, &_lock);
|
|
pbo->_args.copy(_args);
|
|
_retval = getPyNone();
|
|
pbo->clamp(min, max);
|
|
pbo->_args.check();
|
|
}
|
|
pbFinalizePlugin(pbo->getParent(), "MeshDataImpl::clamp", !noTiming);
|
|
return _retval;
|
|
}
|
|
catch (std::exception &e) {
|
|
pbSetError("MeshDataImpl::clamp", e.what());
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
void clampMin(Real vmin);
|
|
static PyObject *_W_31(PyObject *_self, PyObject *_linargs, PyObject *_kwds)
|
|
{
|
|
try {
|
|
PbArgs _args(_linargs, _kwds);
|
|
MeshDataImpl *pbo = dynamic_cast<MeshDataImpl *>(Pb::objFromPy(_self));
|
|
bool noTiming = _args.getOpt<bool>("notiming", -1, 0);
|
|
pbPreparePlugin(pbo->getParent(), "MeshDataImpl::clampMin", !noTiming);
|
|
PyObject *_retval = 0;
|
|
{
|
|
ArgLocker _lock;
|
|
Real vmin = _args.get<Real>("vmin", 0, &_lock);
|
|
pbo->_args.copy(_args);
|
|
_retval = getPyNone();
|
|
pbo->clampMin(vmin);
|
|
pbo->_args.check();
|
|
}
|
|
pbFinalizePlugin(pbo->getParent(), "MeshDataImpl::clampMin", !noTiming);
|
|
return _retval;
|
|
}
|
|
catch (std::exception &e) {
|
|
pbSetError("MeshDataImpl::clampMin", e.what());
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
void clampMax(Real vmax);
|
|
static PyObject *_W_32(PyObject *_self, PyObject *_linargs, PyObject *_kwds)
|
|
{
|
|
try {
|
|
PbArgs _args(_linargs, _kwds);
|
|
MeshDataImpl *pbo = dynamic_cast<MeshDataImpl *>(Pb::objFromPy(_self));
|
|
bool noTiming = _args.getOpt<bool>("notiming", -1, 0);
|
|
pbPreparePlugin(pbo->getParent(), "MeshDataImpl::clampMax", !noTiming);
|
|
PyObject *_retval = 0;
|
|
{
|
|
ArgLocker _lock;
|
|
Real vmax = _args.get<Real>("vmax", 0, &_lock);
|
|
pbo->_args.copy(_args);
|
|
_retval = getPyNone();
|
|
pbo->clampMax(vmax);
|
|
pbo->_args.check();
|
|
}
|
|
pbFinalizePlugin(pbo->getParent(), "MeshDataImpl::clampMax", !noTiming);
|
|
return _retval;
|
|
}
|
|
catch (std::exception &e) {
|
|
pbSetError("MeshDataImpl::clampMax", e.what());
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
Real getMaxAbs();
|
|
static PyObject *_W_33(PyObject *_self, PyObject *_linargs, PyObject *_kwds)
|
|
{
|
|
try {
|
|
PbArgs _args(_linargs, _kwds);
|
|
MeshDataImpl *pbo = dynamic_cast<MeshDataImpl *>(Pb::objFromPy(_self));
|
|
bool noTiming = _args.getOpt<bool>("notiming", -1, 0);
|
|
pbPreparePlugin(pbo->getParent(), "MeshDataImpl::getMaxAbs", !noTiming);
|
|
PyObject *_retval = 0;
|
|
{
|
|
ArgLocker _lock;
|
|
pbo->_args.copy(_args);
|
|
_retval = toPy(pbo->getMaxAbs());
|
|
pbo->_args.check();
|
|
}
|
|
pbFinalizePlugin(pbo->getParent(), "MeshDataImpl::getMaxAbs", !noTiming);
|
|
return _retval;
|
|
}
|
|
catch (std::exception &e) {
|
|
pbSetError("MeshDataImpl::getMaxAbs", e.what());
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
Real getMax();
|
|
static PyObject *_W_34(PyObject *_self, PyObject *_linargs, PyObject *_kwds)
|
|
{
|
|
try {
|
|
PbArgs _args(_linargs, _kwds);
|
|
MeshDataImpl *pbo = dynamic_cast<MeshDataImpl *>(Pb::objFromPy(_self));
|
|
bool noTiming = _args.getOpt<bool>("notiming", -1, 0);
|
|
pbPreparePlugin(pbo->getParent(), "MeshDataImpl::getMax", !noTiming);
|
|
PyObject *_retval = 0;
|
|
{
|
|
ArgLocker _lock;
|
|
pbo->_args.copy(_args);
|
|
_retval = toPy(pbo->getMax());
|
|
pbo->_args.check();
|
|
}
|
|
pbFinalizePlugin(pbo->getParent(), "MeshDataImpl::getMax", !noTiming);
|
|
return _retval;
|
|
}
|
|
catch (std::exception &e) {
|
|
pbSetError("MeshDataImpl::getMax", e.what());
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
Real getMin();
|
|
static PyObject *_W_35(PyObject *_self, PyObject *_linargs, PyObject *_kwds)
|
|
{
|
|
try {
|
|
PbArgs _args(_linargs, _kwds);
|
|
MeshDataImpl *pbo = dynamic_cast<MeshDataImpl *>(Pb::objFromPy(_self));
|
|
bool noTiming = _args.getOpt<bool>("notiming", -1, 0);
|
|
pbPreparePlugin(pbo->getParent(), "MeshDataImpl::getMin", !noTiming);
|
|
PyObject *_retval = 0;
|
|
{
|
|
ArgLocker _lock;
|
|
pbo->_args.copy(_args);
|
|
_retval = toPy(pbo->getMin());
|
|
pbo->_args.check();
|
|
}
|
|
pbFinalizePlugin(pbo->getParent(), "MeshDataImpl::getMin", !noTiming);
|
|
return _retval;
|
|
}
|
|
catch (std::exception &e) {
|
|
pbSetError("MeshDataImpl::getMin", e.what());
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
T sum(const MeshDataImpl<int> *t = NULL, const int itype = 0) const;
|
|
static PyObject *_W_36(PyObject *_self, PyObject *_linargs, PyObject *_kwds)
|
|
{
|
|
try {
|
|
PbArgs _args(_linargs, _kwds);
|
|
MeshDataImpl *pbo = dynamic_cast<MeshDataImpl *>(Pb::objFromPy(_self));
|
|
bool noTiming = _args.getOpt<bool>("notiming", -1, 0);
|
|
pbPreparePlugin(pbo->getParent(), "MeshDataImpl::sum", !noTiming);
|
|
PyObject *_retval = 0;
|
|
{
|
|
ArgLocker _lock;
|
|
const MeshDataImpl<int> *t = _args.getPtrOpt<MeshDataImpl<int>>("t", 0, NULL, &_lock);
|
|
const int itype = _args.getOpt<int>("itype", 1, 0, &_lock);
|
|
pbo->_args.copy(_args);
|
|
_retval = toPy(pbo->sum(t, itype));
|
|
pbo->_args.check();
|
|
}
|
|
pbFinalizePlugin(pbo->getParent(), "MeshDataImpl::sum", !noTiming);
|
|
return _retval;
|
|
}
|
|
catch (std::exception &e) {
|
|
pbSetError("MeshDataImpl::sum", e.what());
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
Real sumSquare() const;
|
|
static PyObject *_W_37(PyObject *_self, PyObject *_linargs, PyObject *_kwds)
|
|
{
|
|
try {
|
|
PbArgs _args(_linargs, _kwds);
|
|
MeshDataImpl *pbo = dynamic_cast<MeshDataImpl *>(Pb::objFromPy(_self));
|
|
bool noTiming = _args.getOpt<bool>("notiming", -1, 0);
|
|
pbPreparePlugin(pbo->getParent(), "MeshDataImpl::sumSquare", !noTiming);
|
|
PyObject *_retval = 0;
|
|
{
|
|
ArgLocker _lock;
|
|
pbo->_args.copy(_args);
|
|
_retval = toPy(pbo->sumSquare());
|
|
pbo->_args.check();
|
|
}
|
|
pbFinalizePlugin(pbo->getParent(), "MeshDataImpl::sumSquare", !noTiming);
|
|
return _retval;
|
|
}
|
|
catch (std::exception &e) {
|
|
pbSetError("MeshDataImpl::sumSquare", e.what());
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
Real sumMagnitude() const;
|
|
static PyObject *_W_38(PyObject *_self, PyObject *_linargs, PyObject *_kwds)
|
|
{
|
|
try {
|
|
PbArgs _args(_linargs, _kwds);
|
|
MeshDataImpl *pbo = dynamic_cast<MeshDataImpl *>(Pb::objFromPy(_self));
|
|
bool noTiming = _args.getOpt<bool>("notiming", -1, 0);
|
|
pbPreparePlugin(pbo->getParent(), "MeshDataImpl::sumMagnitude", !noTiming);
|
|
PyObject *_retval = 0;
|
|
{
|
|
ArgLocker _lock;
|
|
pbo->_args.copy(_args);
|
|
_retval = toPy(pbo->sumMagnitude());
|
|
pbo->_args.check();
|
|
}
|
|
pbFinalizePlugin(pbo->getParent(), "MeshDataImpl::sumMagnitude", !noTiming);
|
|
return _retval;
|
|
}
|
|
catch (std::exception &e) {
|
|
pbSetError("MeshDataImpl::sumMagnitude", e.what());
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
//! special, set if int flag in t has "flag"
|
|
void setConstIntFlag(T s, const MeshDataImpl<int> &t, const int flag);
|
|
static PyObject *_W_39(PyObject *_self, PyObject *_linargs, PyObject *_kwds)
|
|
{
|
|
try {
|
|
PbArgs _args(_linargs, _kwds);
|
|
MeshDataImpl *pbo = dynamic_cast<MeshDataImpl *>(Pb::objFromPy(_self));
|
|
bool noTiming = _args.getOpt<bool>("notiming", -1, 0);
|
|
pbPreparePlugin(pbo->getParent(), "MeshDataImpl::setConstIntFlag", !noTiming);
|
|
PyObject *_retval = 0;
|
|
{
|
|
ArgLocker _lock;
|
|
T s = _args.get<T>("s", 0, &_lock);
|
|
const MeshDataImpl<int> &t = *_args.getPtr<MeshDataImpl<int>>("t", 1, &_lock);
|
|
const int flag = _args.get<int>("flag", 2, &_lock);
|
|
pbo->_args.copy(_args);
|
|
_retval = getPyNone();
|
|
pbo->setConstIntFlag(s, t, flag);
|
|
pbo->_args.check();
|
|
}
|
|
pbFinalizePlugin(pbo->getParent(), "MeshDataImpl::setConstIntFlag", !noTiming);
|
|
return _retval;
|
|
}
|
|
catch (std::exception &e) {
|
|
pbSetError("MeshDataImpl::setConstIntFlag", e.what());
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
void printMdata(IndexInt start = -1, IndexInt stop = -1, bool printIndex = false);
|
|
static PyObject *_W_40(PyObject *_self, PyObject *_linargs, PyObject *_kwds)
|
|
{
|
|
try {
|
|
PbArgs _args(_linargs, _kwds);
|
|
MeshDataImpl *pbo = dynamic_cast<MeshDataImpl *>(Pb::objFromPy(_self));
|
|
bool noTiming = _args.getOpt<bool>("notiming", -1, 0);
|
|
pbPreparePlugin(pbo->getParent(), "MeshDataImpl::printMdata", !noTiming);
|
|
PyObject *_retval = 0;
|
|
{
|
|
ArgLocker _lock;
|
|
IndexInt start = _args.getOpt<IndexInt>("start", 0, -1, &_lock);
|
|
IndexInt stop = _args.getOpt<IndexInt>("stop", 1, -1, &_lock);
|
|
bool printIndex = _args.getOpt<bool>("printIndex", 2, false, &_lock);
|
|
pbo->_args.copy(_args);
|
|
_retval = getPyNone();
|
|
pbo->printMdata(start, stop, printIndex);
|
|
pbo->_args.check();
|
|
}
|
|
pbFinalizePlugin(pbo->getParent(), "MeshDataImpl::printMdata", !noTiming);
|
|
return _retval;
|
|
}
|
|
catch (std::exception &e) {
|
|
pbSetError("MeshDataImpl::printMdata", e.what());
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
//! file io
|
|
void save(const std::string name);
|
|
static PyObject *_W_41(PyObject *_self, PyObject *_linargs, PyObject *_kwds)
|
|
{
|
|
try {
|
|
PbArgs _args(_linargs, _kwds);
|
|
MeshDataImpl *pbo = dynamic_cast<MeshDataImpl *>(Pb::objFromPy(_self));
|
|
bool noTiming = _args.getOpt<bool>("notiming", -1, 0);
|
|
pbPreparePlugin(pbo->getParent(), "MeshDataImpl::save", !noTiming);
|
|
PyObject *_retval = 0;
|
|
{
|
|
ArgLocker _lock;
|
|
const std::string name = _args.get<std::string>("name", 0, &_lock);
|
|
pbo->_args.copy(_args);
|
|
_retval = getPyNone();
|
|
pbo->save(name);
|
|
pbo->_args.check();
|
|
}
|
|
pbFinalizePlugin(pbo->getParent(), "MeshDataImpl::save", !noTiming);
|
|
return _retval;
|
|
}
|
|
catch (std::exception &e) {
|
|
pbSetError("MeshDataImpl::save", e.what());
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
void load(const std::string name);
|
|
static PyObject *_W_42(PyObject *_self, PyObject *_linargs, PyObject *_kwds)
|
|
{
|
|
try {
|
|
PbArgs _args(_linargs, _kwds);
|
|
MeshDataImpl *pbo = dynamic_cast<MeshDataImpl *>(Pb::objFromPy(_self));
|
|
bool noTiming = _args.getOpt<bool>("notiming", -1, 0);
|
|
pbPreparePlugin(pbo->getParent(), "MeshDataImpl::load", !noTiming);
|
|
PyObject *_retval = 0;
|
|
{
|
|
ArgLocker _lock;
|
|
const std::string name = _args.get<std::string>("name", 0, &_lock);
|
|
pbo->_args.copy(_args);
|
|
_retval = getPyNone();
|
|
pbo->load(name);
|
|
pbo->_args.check();
|
|
}
|
|
pbFinalizePlugin(pbo->getParent(), "MeshDataImpl::load", !noTiming);
|
|
return _retval;
|
|
}
|
|
catch (std::exception &e) {
|
|
pbSetError("MeshDataImpl::load", e.what());
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
//! get data pointer of mesh data
|
|
std::string getDataPointer();
|
|
static PyObject *_W_43(PyObject *_self, PyObject *_linargs, PyObject *_kwds)
|
|
{
|
|
try {
|
|
PbArgs _args(_linargs, _kwds);
|
|
MeshDataImpl *pbo = dynamic_cast<MeshDataImpl *>(Pb::objFromPy(_self));
|
|
bool noTiming = _args.getOpt<bool>("notiming", -1, 0);
|
|
pbPreparePlugin(pbo->getParent(), "MeshDataImpl::getDataPointer", !noTiming);
|
|
PyObject *_retval = 0;
|
|
{
|
|
ArgLocker _lock;
|
|
pbo->_args.copy(_args);
|
|
_retval = toPy(pbo->getDataPointer());
|
|
pbo->_args.check();
|
|
}
|
|
pbFinalizePlugin(pbo->getParent(), "MeshDataImpl::getDataPointer", !noTiming);
|
|
return _retval;
|
|
}
|
|
catch (std::exception &e) {
|
|
pbSetError("MeshDataImpl::getDataPointer", e.what());
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
protected:
|
|
//! data storage
|
|
std::vector<T> mData;
|
|
|
|
//! optionally , we might have an associated grid from which to grab new data
|
|
Grid<T> *mpGridSource; //! unfortunately , we need to distinguish mac vs regular vec3
|
|
bool mGridSourceMAC;
|
|
public:
|
|
PbArgs _args;
|
|
}
|
|
#define _C_MeshDataImpl
|
|
;
|
|
|
|
// ***************************************************************************************************************
|
|
// Implementation
|
|
|
|
template<class T>
|
|
void SimpleNodeChannel<T>::renumber(const std::vector<int> &newIndex, int newsize)
|
|
{
|
|
for (size_t i = 0; i < newIndex.size(); i++) {
|
|
if (newIndex[i] != -1)
|
|
data[newIndex[i]] = data[newsize + i];
|
|
}
|
|
data.resize(newsize);
|
|
}
|
|
|
|
inline void MeshDataBase::checkNodeIndex(IndexInt idx) const
|
|
{
|
|
IndexInt mySize = this->getSizeSlow();
|
|
if (idx < 0 || idx > mySize) {
|
|
errMsg("MeshData "
|
|
<< " size " << mySize << " : index " << idx << " out of bound ");
|
|
}
|
|
if (mMesh && mMesh->getSizeSlow() != mySize) {
|
|
errMsg("MeshData "
|
|
<< " size " << mySize << " does not match parent! (" << mMesh->getSizeSlow() << ") ");
|
|
}
|
|
}
|
|
|
|
template<class T> void MeshDataImpl<T>::clear()
|
|
{
|
|
for (IndexInt i = 0; i < (IndexInt)mData.size(); ++i)
|
|
mData[i] = 0.;
|
|
}
|
|
|
|
} // namespace Manta
|
|
#endif
|