This repository has been archived on 2023-10-09. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
blender-archive/extern/mantaflow/helper/pwrapper/pvec3.cpp
2020-11-06 12:06:05 +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"},
{nullptr} // Sentinel
};
static PyMethodDef PbVec3Methods[] = {
//{"name", (PyCFunction)Noddy_name, METH_NOARGS, "Return the name, combining the first and last
//name" },
{nullptr} // 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(nullptr, 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[] = {
{nullptr} // 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"},
{nullptr} // 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(nullptr, 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 */
nullptr, // &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