diff options
Diffstat (limited to 'extern/mantaflow/helper/pwrapper/pclass.cpp')
-rw-r--r-- | extern/mantaflow/helper/pwrapper/pclass.cpp | 220 |
1 files changed, 220 insertions, 0 deletions
diff --git a/extern/mantaflow/helper/pwrapper/pclass.cpp b/extern/mantaflow/helper/pwrapper/pclass.cpp new file mode 100644 index 00000000000..a95254ebe11 --- /dev/null +++ b/extern/mantaflow/helper/pwrapper/pclass.cpp @@ -0,0 +1,220 @@ +/****************************************************************************** + * + * 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 + * + * Functions for property setting/getting via python + * + ******************************************************************************/ + +#include "pythonInclude.h" +#include "structmember.h" +#include "manta.h" +#include "general.h" +#include "timing.h" + +#ifdef GUI +# include <QMutex> +#else +class QMutex { + public: + void lock(){}; + void unlock(){}; + bool tryLock() + { + return true; + }; +}; +#endif + +using namespace std; +namespace Manta { + +//****************************************************************************** +// Free functions + +void pbPreparePlugin(FluidSolver *parent, const string &name, bool doTime) +{ + if (doTime) + TimingData::instance().start(parent, name); +} + +void pbFinalizePlugin(FluidSolver *parent, const string &name, bool doTime) +{ + if (doTime) + TimingData::instance().stop(parent, name); + + // GUI update, also print name of parent if there's more than one + std::ostringstream msg; + if (name != "FluidSolver::step") { + if (parent && (parent->getNumInstances() > 0)) + msg << parent->getName() << string("."); + msg << name; + } + updateQtGui(false, 0, 0., msg.str()); + + debMsg(name << " done", 3); + // name unnamed PbClass Objects from var name + PbClass::renameObjects(); +} + +void pbSetError(const string &fn, const string &ex) +{ + debMsg("Error in " << fn, 1); + if (!ex.empty()) + PyErr_SetString(PyExc_RuntimeError, ex.c_str()); +} + +//****************************************************************************** +// Helpers + +string PbTypeVec::str() const +{ + if (T.empty()) + return ""; + string s = "<"; + for (int i = 0; i < (int)T.size(); i++) { + s += T[i].str(); + s += (i != (int)T.size() - 1) ? ',' : '>'; + } + return s; +} +string PbType::str() const +{ + if (S == "float") + return "Real"; + if (S == "manta.vec3") + return "Vec3"; + return S; +} + +//****************************************************************************** +// PbClass + +vector<PbClass *> PbClass::mInstances; + +PbClass::PbClass(FluidSolver *parent, const string &name, PyObject *obj) + : mMutex(NULL), mParent(parent), mPyObject(obj), mName(name), mHidden(false) +{ + mMutex = new QMutex(); +} + +PbClass::PbClass(const PbClass &a) + : mMutex(NULL), mParent(a.mParent), mPyObject(0), mName("_unnamed"), mHidden(false) +{ + mMutex = new QMutex(); +} + +PbClass::~PbClass() +{ + for (vector<PbClass *>::iterator it = mInstances.begin(); it != mInstances.end(); ++it) { + if (*it == this) { + mInstances.erase(it); + break; + } + } + delete mMutex; +} + +void PbClass::lock() +{ + mMutex->lock(); +} +void PbClass::unlock() +{ + mMutex->unlock(); +} +bool PbClass::tryLock() +{ + return mMutex->tryLock(); +} + +PbClass *PbClass::getInstance(int idx) +{ + if (idx < 0 || idx > (int)mInstances.size()) + errMsg("PbClass::getInstance(): invalid index"); + return mInstances[idx]; +} + +int PbClass::getNumInstances() +{ + return mInstances.size(); +} + +bool PbClass::isNullRef(PyObject *obj) +{ + return PyLong_Check(obj) && PyLong_AsDouble(obj) == 0; +} + +bool PbClass::isNoneRef(PyObject *obj) +{ + return (obj == Py_None); +} + +void PbClass::registerObject(PyObject *obj, PbArgs *args) +{ + // cross link + Pb::setReference(this, obj); + mPyObject = obj; + + mInstances.push_back(this); + + if (args) { + string _name = args->getOpt<std::string>("name", -1, ""); + if (!_name.empty()) + setName(_name); + } +} + +PbClass *PbClass::createPyObject(const string &classname, + const string &name, + PbArgs &args, + PbClass *parent) +{ + return Pb::createPy(classname, name, args, parent); +} + +void PbClass::checkParent() +{ + if (getParent() == NULL) { + errMsg("New class " + mName + ": no parent given -- specify using parent=xxx !"); + } +} +//! Assign unnamed PbClass objects their Python variable name +void PbClass::renameObjects() +{ + PyObject *sys_mod_dict = PyImport_GetModuleDict(); + PyObject *loc_mod = PyMapping_GetItemString(sys_mod_dict, (char *)"__main__"); + if (!loc_mod) + return; + PyObject *locdict = PyObject_GetAttrString(loc_mod, "__dict__"); + if (!locdict) + return; + + // iterate all PbClass instances + for (size_t i = 0; i < mInstances.size(); i++) { + PbClass *obj = mInstances[i]; + if (obj->getName().empty()) { + // empty, try to find instance in module local dictionary + + PyObject *lkey, *lvalue; + Py_ssize_t lpos = 0; + while (PyDict_Next(locdict, &lpos, &lkey, &lvalue)) { + if (lvalue == obj->mPyObject) { + string varName = fromPy<string>(PyObject_Str(lkey)); + obj->setName(varName); + // cout << "assigning variable name '" << varName << "' to unnamed instance" << endl; + break; + } + } + } + } + Py_DECREF(locdict); + Py_DECREF(loc_mod); +} + +} // namespace Manta |