blender/extern/mantaflow/helper/pwrapper/pvec3.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

415 lines
14 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
*
* Vec3 class extension for python
*
******************************************************************************/
#include "pythonInclude.h"
#include <string>
#include <sstream>
#include "vectorbase.h"
#include "structmember.h"
#include "manta.h"
using namespace std;
namespace Manta {
extern PyTypeObject PbVec3Type;
struct PbVec3 {
PyObject_HEAD float data[3];
};
static void PbVec3Dealloc(PbVec3 *self)
{
Py_TYPE(self)->tp_free((PyObject *)self);
}
static PyObject *PbVec3New(PyTypeObject *type, PyObject *args, PyObject *kwds)
{
return type->tp_alloc(type, 0);
}
static int PbVec3Init(PbVec3 *self, PyObject *args, PyObject *kwds)
{
float x1 = numeric_limits<float>::quiet_NaN(), x2 = x1, x3 = x1;
if (!PyArg_ParseTuple(args, "|fff", &x1, &x2, &x3))
return -1;
if (!c_isnan(x1)) {
self->data[0] = x1;
if (!c_isnan(x2) && !c_isnan(x3)) {
self->data[1] = x2;
self->data[2] = x3;
}
else {
if (!c_isnan(x2) || !c_isnan(x3)) {
errMsg("Invalid partial init of vec3");
}
self->data[1] = x1;
self->data[2] = x1;
}
}
else {
self->data[0] = 0;
self->data[1] = 0;
self->data[2] = 0;
}
return 0;
}
static PyObject *PbVec3Repr(PbVec3 *self)
{
Manta::Vec3 v(self->data[0], self->data[1], self->data[2]);
return PyUnicode_FromFormat(v.toString().c_str());
}
static PyMemberDef PbVec3Members[] = {
{(char *)"x", T_FLOAT, offsetof(PbVec3, data), 0, (char *)"X"},
{(char *)"y", T_FLOAT, offsetof(PbVec3, data) + sizeof(float), 0, (char *)"Y"},
{(char *)"z", T_FLOAT, offsetof(PbVec3, data) + sizeof(float) * 2, 0, (char *)"Z"},
{NULL} // Sentinel
};
static PyMethodDef PbVec3Methods[] = {
//{"name", (PyCFunction)Noddy_name, METH_NOARGS, "Return the name, combining the first and last
//name" },
{NULL} // Sentinel
};
// operator overloads
inline PyObject *PbNew(const Vec3 &a)
{
PbVec3 *obj = (PbVec3 *)PbVec3New(&PbVec3Type, 0, 0);
obj->data[0] = a.x;
obj->data[1] = a.y;
obj->data[2] = a.z;
return (PyObject *)obj;
}
#define CONVERTVEC(obj) \
Vec3 v##obj; \
if (PyObject_TypeCheck(obj, &PbVec3Type)) \
v##obj = Vec3(&(((PbVec3 *)obj)->data[0])); \
else if (PyFloat_Check(obj)) \
v##obj = Vec3(PyFloat_AsDouble(obj)); \
else if (PyLong_Check(obj)) \
v##obj = Vec3(PyLong_AsDouble(obj)); \
else { \
Py_INCREF(Py_NotImplemented); \
return Py_NotImplemented; \
}
#define OPHEADER \
if (!PyObject_TypeCheck(a, &PbVec3Type) && !PyObject_TypeCheck(b, &PbVec3Type)) { \
Py_INCREF(Py_NotImplemented); \
return Py_NotImplemented; \
} \
CONVERTVEC(a) \
CONVERTVEC(b)
#define OPHEADER1 \
if (!PyObject_TypeCheck(a, &PbVec3Type)) { \
Py_INCREF(Py_NotImplemented); \
return Py_NotImplemented; \
} \
CONVERTVEC(a)
PyObject *PbVec3Add(PyObject *a, PyObject *b)
{
OPHEADER
return PbNew(va + vb);
}
PyObject *PbVec3Sub(PyObject *a, PyObject *b)
{
OPHEADER
return PbNew(va - vb);
}
PyObject *PbVec3Mult(PyObject *a, PyObject *b)
{
OPHEADER
return PbNew(va * vb);
}
PyObject *PbVec3Div(PyObject *a, PyObject *b)
{
OPHEADER
return PbNew(va / vb);
}
PyObject *PbVec3Negative(PyObject *a)
{
OPHEADER1
return PbNew(-va);
}
// numbers are defined subtely different in Py3 (WTF?)
#if PY_MAJOR_VERSION >= 3
static PyNumberMethods PbVec3NumberMethods = {
(binaryfunc)PbVec3Add, // binaryfunc nb_add;
(binaryfunc)PbVec3Sub, // binaryfunc nb_sub;
(binaryfunc)PbVec3Mult, // binaryfunc nb_mult;
0, // binaryfunc nb_remainder;
0, // binaryfunc nb_divmod;
0, // ternaryfunc nb_power;
(unaryfunc)PbVec3Negative, // unaryfunc nb_negative;
0, // unaryfunc nb_positive;
0, // unaryfunc nb_absolute;
0, // inquiry nb_bool;
0, // unaryfunc nb_invert;
0, // binaryfunc nb_lshift;
0, // binaryfunc nb_rshift;
0, // binaryfunc nb_and;
0, // binaryfunc nb_xor;
0, // binaryfunc nb_or;
0, // unaryfunc nb_int;
0, // void *nb_reserved;
0, // unaryfunc nb_float;
0, // binaryfunc nb_inplace_add;
0, // binaryfunc nb_inplace_subtract;
0, // binaryfunc nb_inplace_multiply;
0, // binaryfunc nb_inplace_remainder;
0, // ternaryfunc nb_inplace_power;
0, // binaryfunc nb_inplace_lshift;
0, // binaryfunc nb_inplace_rshift;
0, // binaryfunc nb_inplace_and;
0, // binaryfunc nb_inplace_xor;
0, // binaryfunc nb_inplace_or;
0, // binaryfunc nb_floor_divide;
(binaryfunc)PbVec3Div, // binaryfunc nb_true_divide;
0, // binaryfunc nb_inplace_floor_divide;
0, // binaryfunc nb_inplace_true_divide;
0 // unaryfunc nb_index;
};
#else
static PyNumberMethods PbVec3NumberMethods = {
(binaryfunc)PbVec3Add, // binaryfunc nb_add;
(binaryfunc)PbVec3Sub, // binaryfunc nb_sub;
(binaryfunc)PbVec3Mult, // binaryfunc nb_mult;
0, // binaryfunc nb_divide;
0, // binaryfunc nb_remainder;
0, // binaryfunc nb_divmod;
0, // ternaryfunc nb_power;
(unaryfunc)PbVec3Negative, // unaryfunc nb_negative;
0, // unaryfunc nb_positive;
0, // unaryfunc nb_absolute;
0, // inquiry nb_nonzero;
0, // unaryfunc nb_invert;
0, // binaryfunc nb_lshift;
0, // binaryfunc nb_rshift;
0, // binaryfunc nb_and;
0, // binaryfunc nb_xor;
0, // binaryfunc nb_or;
0, // coercion nb_coerce;
0, // unaryfunc nb_int;
0, // unaryfunc nb_long;
0, // unaryfunc nb_float;
0, // unaryfunc nb_oct;
0, // unaryfunc nb_hex;
0, // binaryfunc nb_inplace_add;
0, // binaryfunc nb_inplace_subtract;
0, // binaryfunc nb_inplace_multiply;
0, // binaryfunc nb_inplace_divide;
0, // binaryfunc nb_inplace_remainder;
0, // ternaryfunc nb_inplace_power;
0, // binaryfunc nb_inplace_lshift;
0, // binaryfunc nb_inplace_rshift;
0, // binaryfunc nb_inplace_and;
0, // binaryfunc nb_inplace_xor;
0, // binaryfunc nb_inplace_or;
0, // binaryfunc nb_floor_divide;
(binaryfunc)PbVec3Div, // binaryfunc nb_true_divide;
0, // binaryfunc nb_inplace_floor_divide;
0, // binaryfunc nb_inplace_true_divide;
0, // unaryfunc nb_index;
};
#endif
PyTypeObject PbVec3Type = {
PyVarObject_HEAD_INIT(NULL, 0) "manta.vec3", /* tp_name */
sizeof(PbVec3), /* tp_basicsize */
0, /* tp_itemsize */
(destructor)PbVec3Dealloc, /* tp_dealloc */
0, /* tp_print */
0, /* tp_getattr */
0, /* tp_setattr */
0, /* tp_reserved */
(reprfunc)PbVec3Repr, /* tp_repr */
&PbVec3NumberMethods, /* tp_as_number */
0, /* tp_as_sequence */
0, /* tp_as_mapping */
0, /* tp_hash */
0, /* tp_call */
0, /* tp_str */
0, /* tp_getattro */
0, /* tp_setattro */
0, /* tp_as_buffer */
#if PY_MAJOR_VERSION >= 3
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
#else
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_CHECKTYPES, /* tp_flags */
#endif
"float vector type", /* tp_doc */
0, /* tp_traverse */
0, /* tp_clear */
0, /* tp_richcompare */
0, /* tp_weaklistoffset */
0, /* tp_iter */
0, /* tp_iternext */
PbVec3Methods, /* tp_methods */
PbVec3Members, /* tp_members */
0, /* tp_getset */
0, /* tp_base */
0, /* tp_dict */
0, /* tp_descr_get */
0, /* tp_descr_set */
0, /* tp_dictoffset */
(initproc)PbVec3Init, /* tp_init */
0, /* tp_alloc */
PbVec3New, /* tp_new */
};
inline PyObject *castPy(PyTypeObject *p)
{
return reinterpret_cast<PyObject *>(static_cast<void *>(p));
}
// 4d vector
extern PyTypeObject PbVec4Type;
struct PbVec4 {
PyObject_HEAD float data[4];
};
static PyMethodDef PbVec4Methods[] = {
{NULL} // Sentinel
};
static PyMemberDef PbVec4Members[] = {
{(char *)"x", T_FLOAT, offsetof(PbVec4, data), 0, (char *)"X"},
{(char *)"y", T_FLOAT, offsetof(PbVec4, data) + sizeof(float) * 1, 0, (char *)"Y"},
{(char *)"z", T_FLOAT, offsetof(PbVec4, data) + sizeof(float) * 2, 0, (char *)"Z"},
{(char *)"t", T_FLOAT, offsetof(PbVec4, data) + sizeof(float) * 3, 0, (char *)"T"},
{NULL} // Sentinel
};
static void PbVec4Dealloc(PbVec4 *self)
{
Py_TYPE(self)->tp_free((PyObject *)self);
}
static PyObject *PbVec4New(PyTypeObject *type, PyObject *args, PyObject *kwds)
{
return type->tp_alloc(type, 0);
}
static int PbVec4Init(PbVec4 *self, PyObject *args, PyObject *kwds)
{
float x1 = numeric_limits<float>::quiet_NaN(), x2 = x1, x3 = x1, x4 = x1;
if (!PyArg_ParseTuple(args, "|ffff", &x1, &x2, &x3, &x4))
return -1;
if (!c_isnan(x1)) {
self->data[0] = x1;
if (!c_isnan(x2) && !c_isnan(x3) && !c_isnan(x4)) {
self->data[1] = x2;
self->data[2] = x3;
self->data[3] = x4;
}
else {
if (!c_isnan(x2) || !c_isnan(x3) || !c_isnan(x4)) {
errMsg("Invalid partial init of vec4");
}
self->data[1] = self->data[2] = self->data[3] = x1;
}
}
else {
self->data[0] = self->data[1] = self->data[2] = self->data[3] = 0;
}
return 0;
}
static PyObject *PbVec4Repr(PbVec4 *self)
{
Manta::Vec4 v(self->data[0], self->data[1], self->data[2], self->data[3]);
return PyUnicode_FromFormat(v.toString().c_str());
}
PyTypeObject PbVec4Type = {
PyVarObject_HEAD_INIT(NULL, 0) "manta.vec4", /* tp_name */
sizeof(PbVec4), /* tp_basicsize */
0, /* tp_itemsize */
(destructor)PbVec4Dealloc, /* tp_dealloc */
0, /* tp_print */
0, /* tp_getattr */
0, /* tp_setattr */
0, /* tp_reserved */
(reprfunc)PbVec4Repr, /* tp_repr */
NULL, // &PbVec4NumberMethods, /* tp_as_number */
0, /* tp_as_sequence */
0, /* tp_as_mapping */
0, /* tp_hash */
0, /* tp_call */
0, /* tp_str */
0, /* tp_getattro */
0, /* tp_setattro */
0, /* tp_as_buffer */
#if PY_MAJOR_VERSION >= 3
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
#else
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_CHECKTYPES, /* tp_flags */
#endif
"float vector type", /* tp_doc */
0, /* tp_traverse */
0, /* tp_clear */
0, /* tp_richcompare */
0, /* tp_weaklistoffset */
0, /* tp_iter */
0, /* tp_iternext */
PbVec4Methods, /* tp_methods */
PbVec4Members, /* tp_members */
0, /* tp_getset */
0, /* tp_base */
0, /* tp_dict */
0, /* tp_descr_get */
0, /* tp_descr_set */
0, /* tp_dictoffset */
(initproc)PbVec4Init, /* tp_init */
0, /* tp_alloc */
PbVec4New, /* tp_new */
};
// register
void PbVecInitialize(PyObject *module)
{
if (PyType_Ready(&PbVec3Type) < 0)
errMsg("can't initialize Vec3 type");
Py_INCREF(castPy(&PbVec3Type));
PyModule_AddObject(module, "vec3", (PyObject *)&PbVec3Type);
if (PyType_Ready(&PbVec4Type) < 0)
errMsg("can't initialize Vec4 type");
Py_INCREF(castPy(&PbVec4Type));
PyModule_AddObject(module, "vec4", (PyObject *)&PbVec4Type);
}
const static Pb::Register _REG(PbVecInitialize);
} // namespace Manta