forked from bartvdbraak/blender
4ff7c5eed6
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
221 lines
5.0 KiB
C++
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
|