blender/extern/mantaflow/helper/pwrapper/pclass.cpp
Sebastián Barschkis 4ff7c5eed6 Mantaflow [Part 1]: Added preprocessed Mantaflow source files
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
2019-12-16 16:27:26 +01:00

221 lines
5.0 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
*
* 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