forked from bartvdbraak/blender
311031ecd0
Switched from NULL to nullptr.
264 lines
8.3 KiB
C++
264 lines
8.3 KiB
C++
/******************************************************************************
|
|
*
|
|
* 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
|
|
*
|
|
* Python argument wrappers and conversion tools
|
|
*
|
|
******************************************************************************/
|
|
|
|
// -----------------------------------------------------------------
|
|
// NOTE:
|
|
// Do not include this file in user code, include "manta.h" instead
|
|
// -----------------------------------------------------------------
|
|
|
|
#ifdef _MANTA_H
|
|
# ifndef _PCONVERT_H
|
|
# define _PCONVERT_H
|
|
|
|
# include <string>
|
|
# include <map>
|
|
# include <vector>
|
|
|
|
namespace Manta {
|
|
template<class T> class Grid;
|
|
|
|
//! Locks the given PbClass Arguments until ArgLocker goes out of scope
|
|
struct ArgLocker {
|
|
void add(PbClass *p);
|
|
~ArgLocker();
|
|
std::vector<PbClass *> locks;
|
|
};
|
|
|
|
PyObject *getPyNone();
|
|
|
|
// for PbClass-derived classes
|
|
template<class T> T *fromPyPtr(PyObject *obj, std::vector<void *> *tmp)
|
|
{
|
|
if (PbClass::isNullRef(obj) || PbClass::isNoneRef(obj))
|
|
return 0;
|
|
PbClass *pbo = Pb::objFromPy(obj);
|
|
const std::string &type = Namify<T>::S;
|
|
if (!pbo || !(pbo->canConvertTo(type)))
|
|
throw Error("can't convert argument to " + type + "*");
|
|
return (T *)(pbo);
|
|
}
|
|
|
|
template<> float *fromPyPtr<float>(PyObject *obj, std::vector<void *> *tmp);
|
|
template<> double *fromPyPtr<double>(PyObject *obj, std::vector<void *> *tmp);
|
|
template<> int *fromPyPtr<int>(PyObject *obj, std::vector<void *> *tmp);
|
|
template<> std::string *fromPyPtr<std::string>(PyObject *obj, std::vector<void *> *tmp);
|
|
template<> bool *fromPyPtr<bool>(PyObject *obj, std::vector<void *> *tmp);
|
|
template<> Vec3 *fromPyPtr<Vec3>(PyObject *obj, std::vector<void *> *tmp);
|
|
template<> Vec3i *fromPyPtr<Vec3i>(PyObject *obj, std::vector<void *> *tmp);
|
|
template<> Vec4 *fromPyPtr<Vec4>(PyObject *obj, std::vector<void *> *tmp);
|
|
template<> Vec4i *fromPyPtr<Vec4i>(PyObject *obj, std::vector<void *> *tmp);
|
|
template<>
|
|
std::vector<PbClass *> *fromPyPtr<std::vector<PbClass *>>(PyObject *obj, std::vector<void *> *tmp);
|
|
template<>
|
|
std::vector<float> *fromPyPtr<std::vector<float>>(PyObject *obj, std::vector<void *> *tmp);
|
|
|
|
PyObject *incref(PyObject *obj);
|
|
template<class T> PyObject *toPy(const T &v)
|
|
{
|
|
PyObject *obj = v.getPyObject();
|
|
if (obj) {
|
|
return incref(obj);
|
|
}
|
|
T *co = new T(v);
|
|
const std::string &type = Namify<typename remove_pointers<T>::type>::S;
|
|
return Pb::copyObject(co, type);
|
|
}
|
|
template<class T> bool isPy(PyObject *obj)
|
|
{
|
|
if (PbClass::isNullRef(obj) || PbClass::isNoneRef(obj))
|
|
return false;
|
|
PbClass *pbo = Pb::objFromPy(obj);
|
|
const std::string &type = Namify<typename remove_pointers<T>::type>::S;
|
|
return pbo && pbo->canConvertTo(type);
|
|
}
|
|
|
|
template<class T> T fromPy(PyObject *obj)
|
|
{
|
|
throw Error(
|
|
"Unknown type conversion. Did you pass a PbClass by value? Instead always pass "
|
|
"grids/particlesystems/etc. by reference or using a pointer.");
|
|
}
|
|
|
|
// builtin types
|
|
template<> float fromPy<float>(PyObject *obj);
|
|
template<> double fromPy<double>(PyObject *obj);
|
|
template<> int fromPy<int>(PyObject *obj);
|
|
template<> PyObject *fromPy<PyObject *>(PyObject *obj);
|
|
template<> std::string fromPy<std::string>(PyObject *obj);
|
|
template<> const char *fromPy<const char *>(PyObject *obj);
|
|
template<> bool fromPy<bool>(PyObject *obj);
|
|
template<> Vec3 fromPy<Vec3>(PyObject *obj);
|
|
template<> Vec3i fromPy<Vec3i>(PyObject *obj);
|
|
template<> Vec4 fromPy<Vec4>(PyObject *obj);
|
|
template<> Vec4i fromPy<Vec4i>(PyObject *obj);
|
|
template<> PbType fromPy<PbType>(PyObject *obj);
|
|
template<> PbTypeVec fromPy<PbTypeVec>(PyObject *obj);
|
|
template<> PbClass *fromPy<PbClass *>(PyObject *obj);
|
|
template<> std::vector<PbClass *> fromPy<std::vector<PbClass *>>(PyObject *obj);
|
|
template<> std::vector<float> fromPy<std::vector<float>>(PyObject *obj);
|
|
|
|
template<> PyObject *toPy<int>(const int &v);
|
|
template<> PyObject *toPy<std::string>(const std::string &val);
|
|
template<> PyObject *toPy<float>(const float &v);
|
|
template<> PyObject *toPy<double>(const double &v);
|
|
template<> PyObject *toPy<bool>(const bool &v);
|
|
template<> PyObject *toPy<Vec3i>(const Vec3i &v);
|
|
template<> PyObject *toPy<Vec3>(const Vec3 &v);
|
|
template<> PyObject *toPy<Vec4i>(const Vec4i &v);
|
|
template<> PyObject *toPy<Vec4>(const Vec4 &v);
|
|
typedef PbClass *PbClass_Ptr;
|
|
template<> PyObject *toPy<PbClass *>(const PbClass_Ptr &obj);
|
|
template<> PyObject *toPy<std::vector<PbClass *>>(const std::vector<PbClass *> &vec);
|
|
template<> PyObject *toPy<std::vector<float>>(const std::vector<float> &vec);
|
|
|
|
template<> bool isPy<float>(PyObject *obj);
|
|
template<> bool isPy<double>(PyObject *obj);
|
|
template<> bool isPy<int>(PyObject *obj);
|
|
template<> bool isPy<PyObject *>(PyObject *obj);
|
|
template<> bool isPy<std::string>(PyObject *obj);
|
|
template<> bool isPy<const char *>(PyObject *obj);
|
|
template<> bool isPy<bool>(PyObject *obj);
|
|
template<> bool isPy<Vec3>(PyObject *obj);
|
|
template<> bool isPy<Vec3i>(PyObject *obj);
|
|
template<> bool isPy<Vec4>(PyObject *obj);
|
|
template<> bool isPy<Vec4i>(PyObject *obj);
|
|
template<> bool isPy<PbType>(PyObject *obj);
|
|
template<> bool isPy<std::vector<PbClass *>>(PyObject *obj);
|
|
template<> bool isPy<std::vector<float>>(PyObject *obj);
|
|
|
|
//! Encapsulation of python arguments
|
|
class PbArgs {
|
|
public:
|
|
PbArgs(PyObject *linargs = nullptr, PyObject *dict = nullptr);
|
|
~PbArgs();
|
|
void setup(PyObject *linargs = nullptr, PyObject *dict = nullptr);
|
|
|
|
void check();
|
|
FluidSolver *obtainParent();
|
|
|
|
inline int numLinArgs()
|
|
{
|
|
return mLinData.size();
|
|
}
|
|
|
|
inline bool has(const std::string &key)
|
|
{
|
|
return getItem(key, false) != nullptr;
|
|
}
|
|
inline void deleteItem(const std::string &key)
|
|
{
|
|
if (mData.find(key) != mData.end())
|
|
mData.erase(mData.find(key));
|
|
}
|
|
|
|
inline PyObject *linArgs()
|
|
{
|
|
return mLinArgs;
|
|
}
|
|
inline PyObject *kwds()
|
|
{
|
|
return mKwds;
|
|
}
|
|
|
|
void addLinArg(PyObject *obj);
|
|
|
|
template<class T> inline void add(const std::string &key, T arg)
|
|
{
|
|
DataElement el = {toPy(arg), false};
|
|
mData[key] = el;
|
|
}
|
|
template<class T> inline T get(const std::string &key, int number = -1, ArgLocker *lk = nullptr)
|
|
{
|
|
visit(number, key);
|
|
PyObject *o = getItem(key, false, lk);
|
|
if (o)
|
|
return fromPy<T>(o);
|
|
o = getItem(number, false, lk);
|
|
if (o)
|
|
return fromPy<T>(o);
|
|
errMsg("Argument '" + key + "' is not defined.");
|
|
}
|
|
template<class T>
|
|
inline T getOpt(const std::string &key, int number, T defarg, ArgLocker *lk = nullptr)
|
|
{
|
|
visit(number, key);
|
|
PyObject *o = getItem(key, false, lk);
|
|
if (o)
|
|
return fromPy<T>(o);
|
|
if (number >= 0)
|
|
o = getItem(number, false, lk);
|
|
return (o) ? fromPy<T>(o) : defarg;
|
|
}
|
|
template<class T>
|
|
inline T *getPtrOpt(const std::string &key, int number, T *defarg, ArgLocker *lk = nullptr)
|
|
{
|
|
visit(number, key);
|
|
PyObject *o = getItem(key, false, lk);
|
|
if (o)
|
|
return fromPyPtr<T>(o, &mTmpStorage);
|
|
if (number >= 0)
|
|
o = getItem(number, false, lk);
|
|
return o ? fromPyPtr<T>(o, &mTmpStorage) : defarg;
|
|
}
|
|
template<class T>
|
|
inline T *getPtr(const std::string &key, int number = -1, ArgLocker *lk = nullptr)
|
|
{
|
|
visit(number, key);
|
|
PyObject *o = getItem(key, false, lk);
|
|
if (o)
|
|
return fromPyPtr<T>(o, &mTmpStorage);
|
|
o = getItem(number, false, lk);
|
|
if (o)
|
|
return fromPyPtr<T>(o, &mTmpStorage);
|
|
errMsg("Argument '" + key + "' is not defined.");
|
|
}
|
|
|
|
// automatic template type deduction
|
|
template<class T> bool typeCheck(int num, const std::string &name)
|
|
{
|
|
PyObject *o = getItem(name, false, 0);
|
|
if (!o)
|
|
o = getItem(num, false, 0);
|
|
return o ? isPy<typename remove_pointers<T>::type>(o) : false;
|
|
}
|
|
|
|
PbArgs &operator=(const PbArgs &a); // dummy
|
|
void copy(PbArgs &a);
|
|
void clear();
|
|
void visit(int num, const std::string &key);
|
|
|
|
static PbArgs EMPTY;
|
|
|
|
protected:
|
|
PyObject *getItem(const std::string &key, bool strict, ArgLocker *lk = nullptr);
|
|
PyObject *getItem(size_t number, bool strict, ArgLocker *lk = nullptr);
|
|
|
|
struct DataElement {
|
|
PyObject *obj;
|
|
bool visited;
|
|
};
|
|
std::map<std::string, DataElement> mData;
|
|
std::vector<DataElement> mLinData;
|
|
PyObject *mLinArgs, *mKwds;
|
|
std::vector<void *> mTmpStorage;
|
|
};
|
|
|
|
} // namespace Manta
|
|
|
|
# if NUMPY == 1
|
|
# include "numpyWrap.h"
|
|
# endif
|
|
|
|
# endif
|
|
#endif
|