Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/source
diff options
context:
space:
mode:
authorCampbell Barton <ideasman42@gmail.com>2009-04-21 11:16:29 +0400
committerCampbell Barton <ideasman42@gmail.com>2009-04-21 11:16:29 +0400
commit2d054e00b068786996f9154e378e75f436eca239 (patch)
treebce2e5fcbedd5da38d9775a550271e6fd8b68af8 /source
parent70dae5f49339a791c1c84d72047cde144e4e2843 (diff)
Blender Python API
use getseter's for quat and euler types attributes, python3 compatible module initialization for Mathutils and BGL.
Diffstat (limited to 'source')
-rw-r--r--source/blender/python/api2_2x/BGL.c22
-rw-r--r--source/blender/python/api2_2x/Mathutils.c20
-rw-r--r--source/blender/python/api2_2x/euler.c147
-rw-r--r--source/blender/python/api2_2x/quat.c248
-rw-r--r--source/blender/python/api2_2x/vector.c15
-rw-r--r--source/blender/python/api2_2x/vector.h2
6 files changed, 270 insertions, 184 deletions
diff --git a/source/blender/python/api2_2x/BGL.c b/source/blender/python/api2_2x/BGL.c
index cfbb4611c6c..ddb12eb2338 100644
--- a/source/blender/python/api2_2x/BGL.c
+++ b/source/blender/python/api2_2x/BGL.c
@@ -1085,9 +1085,29 @@ static struct PyMethodDef BGL_methods[] = {
{NULL, NULL, 0, NULL}
};
+#if (PY_VERSION_HEX >= 0x03000000)
+static struct PyModuleDef BGL_module_def = {
+ {}, /* m_base */
+ "BGL", /* m_name */
+ 0, /* m_doc */
+ 0, /* m_size */
+ BGL_methods, /* m_methods */
+ 0, /* m_reload */
+ 0, /* m_traverse */
+ 0, /* m_clear */
+ 0, /* m_free */
+};
+#endif
+
PyObject *BGL_Init(const char *from)
{
- PyObject *mod= Py_InitModule(from, BGL_methods);
+ PyObject *mod;
+#if (PY_VERSION_HEX >= 0x03000000)
+ mod = PyModule_Create(&BGL_module_def);
+#else
+ mod= Py_InitModule(from, BGL_methods);
+#endif
+
PyObject *dict= PyModule_GetDict(mod);
PyObject *item;
if( PyType_Ready( &buffer_Type) < 0)
diff --git a/source/blender/python/api2_2x/Mathutils.c b/source/blender/python/api2_2x/Mathutils.c
index b370aa0e1e8..605b5982137 100644
--- a/source/blender/python/api2_2x/Mathutils.c
+++ b/source/blender/python/api2_2x/Mathutils.c
@@ -108,6 +108,21 @@ struct PyMethodDef M_Mathutils_methods[] = {
};
/*----------------------------MODULE INIT-------------------------*/
/* from can be Blender.Mathutils or GameLogic.Mathutils for the BGE */
+
+#if (PY_VERSION_HEX >= 0x03000000)
+static struct PyModuleDef M_Mathutils_module_def = {
+ {}, /* m_base */
+ "Mathutils", /* m_name */
+ M_Mathutils_doc, /* m_doc */
+ 0, /* m_size */
+ M_Mathutils_methods, /* m_methods */
+ 0, /* m_reload */
+ 0, /* m_traverse */
+ 0, /* m_clear */
+ 0, /* m_free */
+};
+#endif
+
PyObject *Mathutils_Init(const char *from)
{
PyObject *submodule;
@@ -126,7 +141,12 @@ PyObject *Mathutils_Init(const char *from)
if( PyType_Ready( &quaternion_Type ) < 0 )
return NULL;
+#if (PY_VERSION_HEX >= 0x03000000)
+ submodule = PyModule_Create(&M_Mathutils_module_def);
+#else
submodule = Py_InitModule3(from, M_Mathutils_methods, M_Mathutils_doc);
+#endif
+
return (submodule);
}
//-----------------------------METHODS----------------------------
diff --git a/source/blender/python/api2_2x/euler.c b/source/blender/python/api2_2x/euler.c
index e349dd26532..52f1e00221e 100644
--- a/source/blender/python/api2_2x/euler.c
+++ b/source/blender/python/api2_2x/euler.c
@@ -189,71 +189,13 @@ static void Euler_dealloc(EulerObject * self)
}
PyObject_DEL(self);
}
-//----------------------------getattr()(internal) ------------------
-//object.attribute access (get)
-static PyObject *Euler_getattr(EulerObject * self, char *name)
-{
- if(STREQ(name,"x")){
- return PyFloat_FromDouble(self->eul[0]);
- }else if(STREQ(name, "y")){
- return PyFloat_FromDouble(self->eul[1]);
- }else if(STREQ(name, "z")){
- return PyFloat_FromDouble(self->eul[2]);
- }
- if(STREQ(name, "wrapped")){
- if(self->wrapped == Py_WRAP)
- return EXPP_incr_ret((PyObject *)Py_True);
- else
- return EXPP_incr_ret((PyObject *)Py_False);
- }
- return Py_FindMethod(Euler_methods, (PyObject *) self, name);
-}
-//----------------------------setattr()(internal) ------------------
-//object.attribute access (set)
-static int Euler_setattr(EulerObject * self, char *name, PyObject * e)
-{
- PyObject *f = NULL;
-
- f = PyNumber_Float(e);
- if(f == NULL) { // parsed item not a number
- return EXPP_ReturnIntError(PyExc_TypeError,
- "euler.attribute = x: argument not a number\n");
- }
-
- if(STREQ(name,"x")){
- self->eul[0] = (float)PyFloat_AS_DOUBLE(f);
- }else if(STREQ(name, "y")){
- self->eul[1] = (float)PyFloat_AS_DOUBLE(f);
- }else if(STREQ(name, "z")){
- self->eul[2] = (float)PyFloat_AS_DOUBLE(f);
- }else{
- Py_DECREF(f);
- return EXPP_ReturnIntError(PyExc_AttributeError,
- "euler.attribute = x: unknown attribute\n");
- }
- Py_DECREF(f);
- return 0;
-}
//----------------------------print object (internal)--------------
//print the object to screen
static PyObject *Euler_repr(EulerObject * self)
{
- int i;
- char buffer[48], str[1024];
-
- BLI_strncpy(str,"[",1024);
- for(i = 0; i < 3; i++){
- if(i < (2)){
- sprintf(buffer, "%.6f, ", self->eul[i]);
- strcat(str,buffer);
- }else{
- sprintf(buffer, "%.6f", self->eul[i]);
- strcat(str,buffer);
- }
- }
- strcat(str, "](euler)");
-
+ char str[64];
+ sprintf(str, "[%.6f, %.6f, %.6f](euler)", self->eul[0], self->eul[1], self->eul[2]);
return PyString_FromString(str);
}
//------------------------tp_richcmpr
@@ -409,6 +351,83 @@ static PySequenceMethods Euler_SeqMethods = {
(intobjargproc) Euler_ass_item, /* sq_ass_item */
(intintobjargproc) Euler_ass_slice, /* sq_ass_slice */
};
+
+
+
+/*
+ * vector axis, vector.x/y/z/w
+ */
+
+static PyObject *Euler_getAxis( EulerObject * self, void *type )
+{
+ switch( (long)type ) {
+ case 'X': /* these are backwards, but that how it works */
+ return PyFloat_FromDouble(self->eul[0]);
+ case 'Y':
+ return PyFloat_FromDouble(self->eul[1]);
+ case 'Z':
+ return PyFloat_FromDouble(self->eul[2]);
+ }
+
+ PyErr_SetString(PyExc_SystemError, "corrupt euler, cannot get axis");
+ return NULL;
+}
+
+static int Euler_setAxis( EulerObject * self, PyObject * value, void * type )
+{
+ float param= (float)PyFloat_AsDouble( value );
+
+ if (param==-1 && PyErr_Occurred())
+ return EXPP_ReturnIntError( PyExc_TypeError,
+ "expected a number for the vector axis" );
+
+ switch( (long)type ) {
+ case 'X': /* these are backwards, but that how it works */
+ self->eul[0]= param;
+ break;
+ case 'Y':
+ self->eul[1]= param;
+ break;
+ case 'Z':
+ self->eul[2]= param;
+ break;
+ }
+
+ return 0;
+}
+
+static PyObject *Euler_getWrapped( VectorObject * self, void *type )
+{
+ if (self->wrapped == Py_WRAP)
+ Py_RETURN_TRUE;
+ else
+ Py_RETURN_FALSE;
+}
+
+
+/*****************************************************************************/
+/* Python attributes get/set structure: */
+/*****************************************************************************/
+static PyGetSetDef Euler_getseters[] = {
+ {"x",
+ (getter)Euler_getAxis, (setter)Euler_setAxis,
+ "Euler X axis",
+ (void *)'X'},
+ {"y",
+ (getter)Euler_getAxis, (setter)Euler_setAxis,
+ "Euler Y axis",
+ (void *)'Y'},
+ {"z",
+ (getter)Euler_getAxis, (setter)Euler_setAxis,
+ "Euler Z axis",
+ (void *)'Z'},
+ {"wrapped",
+ (getter)Euler_getWrapped, (setter)NULL,
+ "True when this wraps blenders internal data",
+ NULL},
+ {NULL,NULL,NULL,NULL,NULL} /* Sentinel */
+};
+
//------------------PY_OBECT DEFINITION--------------------------
PyTypeObject euler_Type = {
PyObject_HEAD_INIT(NULL) //tp_head
@@ -418,8 +437,8 @@ PyTypeObject euler_Type = {
0, //tp_itemsize
(destructor)Euler_dealloc, //tp_dealloc
0, //tp_print
- (getattrfunc)Euler_getattr, //tp_getattr
- (setattrfunc) Euler_setattr, //tp_setattr
+ 0, //tp_getattr
+ 0, //tp_setattr
0, //tp_compare
(reprfunc) Euler_repr, //tp_repr
0, //tp_as_number
@@ -439,9 +458,9 @@ PyTypeObject euler_Type = {
0, //tp_weaklistoffset
0, //tp_iter
0, //tp_iternext
- 0, //tp_methods
+ Euler_methods, //tp_methods
0, //tp_members
- 0, //tp_getset
+ Euler_getseters, //tp_getset
0, //tp_base
0, //tp_dict
0, //tp_descr_get
diff --git a/source/blender/python/api2_2x/quat.c b/source/blender/python/api2_2x/quat.c
index 7cfc1a7cde8..1871339d0b8 100644
--- a/source/blender/python/api2_2x/quat.c
+++ b/source/blender/python/api2_2x/quat.c
@@ -155,109 +155,13 @@ static void Quaternion_dealloc(QuaternionObject * self)
}
PyObject_DEL(self);
}
-//----------------------------getattr()(internal) ------------------
-//object.attribute access (get)
-static PyObject *Quaternion_getattr(QuaternionObject * self, char *name)
-{
- int x;
- double mag = 0.0f;
- float vec[3];
-
- if(STREQ(name,"w")){
- return PyFloat_FromDouble(self->quat[0]);
- }else if(STREQ(name, "x")){
- return PyFloat_FromDouble(self->quat[1]);
- }else if(STREQ(name, "y")){
- return PyFloat_FromDouble(self->quat[2]);
- }else if(STREQ(name, "z")){
- return PyFloat_FromDouble(self->quat[3]);
- }
- if(STREQ(name, "magnitude")) {
- for(x = 0; x < 4; x++) {
- mag += self->quat[x] * self->quat[x];
- }
- mag = sqrt(mag);
- return PyFloat_FromDouble(mag);
- }
- if(STREQ(name, "angle")) {
- mag = self->quat[0];
- mag = 2 * (saacos(mag));
- mag *= (180 / Py_PI);
- return PyFloat_FromDouble(mag);
- }
- if(STREQ(name, "axis")) {
- mag = self->quat[0] * (Py_PI / 180);
- mag = 2 * (saacos(mag));
- mag = sin(mag / 2);
- for(x = 0; x < 3; x++) {
- vec[x] = (float)(self->quat[x + 1] / mag);
- }
- Normalize(vec);
- //If the axis of rotation is 0,0,0 set it to 1,0,0 - for zero-degree rotations
- if( EXPP_FloatsAreEqual(vec[0], 0.0f, 10) &&
- EXPP_FloatsAreEqual(vec[1], 0.0f, 10) &&
- EXPP_FloatsAreEqual(vec[2], 0.0f, 10) ){
- vec[0] = 1.0f;
- }
- return (PyObject *) newVectorObject(vec, 3, Py_NEW);
- }
- if(STREQ(name, "wrapped")){
- if(self->wrapped == Py_WRAP)
- return EXPP_incr_ret((PyObject *)Py_True);
- else
- return EXPP_incr_ret((PyObject *)Py_False);
- }
-
- return Py_FindMethod(Quaternion_methods, (PyObject *) self, name);
-}
-//----------------------------setattr()(internal) ------------------
-//object.attribute access (set)
-static int Quaternion_setattr(QuaternionObject * self, char *name, PyObject * q)
-{
- PyObject *f = NULL;
-
- f = PyNumber_Float(q);
- if(f == NULL) { // parsed item not a number
- return EXPP_ReturnIntError(PyExc_TypeError,
- "quaternion.attribute = x: argument not a number\n");
- }
- if(STREQ(name,"w")){
- self->quat[0] = (float)PyFloat_AS_DOUBLE(f);
- }else if(STREQ(name, "x")){
- self->quat[1] = (float)PyFloat_AS_DOUBLE(f);
- }else if(STREQ(name, "y")){
- self->quat[2] = (float)PyFloat_AS_DOUBLE(f);
- }else if(STREQ(name, "z")){
- self->quat[3] = (float)PyFloat_AS_DOUBLE(f);
- }else{
- Py_DECREF(f);
- return EXPP_ReturnIntError(PyExc_AttributeError,
- "quaternion.attribute = x: unknown attribute\n");
- }
-
- Py_DECREF(f);
- return 0;
-}
//----------------------------print object (internal)--------------
//print the object to screen
static PyObject *Quaternion_repr(QuaternionObject * self)
{
- int i;
- char buffer[48], str[1024];
-
- BLI_strncpy(str,"[",1024);
- for(i = 0; i < 4; i++){
- if(i < (3)){
- sprintf(buffer, "%.6f, ", self->quat[i]);
- strcat(str,buffer);
- }else{
- sprintf(buffer, "%.6f", self->quat[i]);
- strcat(str,buffer);
- }
- }
- strcat(str, "](quaternion)");
-
+ char str[64];
+ sprintf(str, "[%.6f, %.6f, %.6f, %.6f](quaternion)", self->quat[0], self->quat[1], self->quat[2], self->quat[3]);
return PyString_FromString(str);
}
//------------------------tp_richcmpr
@@ -269,9 +173,9 @@ static PyObject* Quaternion_richcmpr(PyObject *objectA, PyObject *objectB, int c
if (!QuaternionObject_Check(objectA) || !QuaternionObject_Check(objectB)){
if (comparison_type == Py_NE){
- return EXPP_incr_ret(Py_True);
+ Py_RETURN_TRUE;
}else{
- return EXPP_incr_ret(Py_False);
+ Py_RETURN_FALSE;
}
}
quatA = (QuaternionObject*)objectA;
@@ -294,9 +198,9 @@ static PyObject* Quaternion_richcmpr(PyObject *objectA, PyObject *objectB, int c
break;
}
if (result == 1){
- return EXPP_incr_ret(Py_True);
+ Py_RETURN_TRUE;
}else{
- return EXPP_incr_ret(Py_False);
+ Py_RETURN_FALSE;
}
}
//------------------------tp_doc
@@ -576,6 +480,138 @@ static PyNumberMethods Quaternion_NumMethods = {
(unaryfunc) 0, /* __hex__ */
};
+
+
+static PyObject *Quaternion_getAxis( QuaternionObject * self, void *type )
+{
+ switch( (long)type ) {
+ case 'W':
+ return PyFloat_FromDouble(self->quat[0]);
+ case 'X':
+ return PyFloat_FromDouble(self->quat[1]);
+ case 'Y':
+ return PyFloat_FromDouble(self->quat[2]);
+ case 'Z':
+ return PyFloat_FromDouble(self->quat[3]);
+ }
+
+ PyErr_SetString(PyExc_SystemError, "corrupt quaternion, cannot get axis");
+ return NULL;
+}
+
+static int Quaternion_setAxis( QuaternionObject * self, PyObject * value, void * type )
+{
+ float param= (float)PyFloat_AsDouble( value );
+
+ if (param==-1 && PyErr_Occurred())
+ return EXPP_ReturnIntError( PyExc_TypeError,
+ "expected a number for the vector axis" );
+
+ switch( (long)type ) {
+ case 'W':
+ self->quat[0]= param;
+ break;
+ case 'X':
+ self->quat[1]= param;
+ break;
+ case 'Y':
+ self->quat[2]= param;
+ break;
+ case 'Z':
+ self->quat[3]= param;
+ break;
+ }
+
+ return 0;
+}
+
+static PyObject *Quaternion_getWrapped( QuaternionObject * self, void *type )
+{
+ if (self->wrapped == Py_WRAP)
+ Py_RETURN_TRUE;
+ else
+ Py_RETURN_FALSE;
+}
+
+static PyObject *Quaternion_getMagnitude( QuaternionObject * self, void *type )
+{
+ double mag = 0.0;
+ int i;
+ for(i = 0; i < 4; i++) {
+ mag += self->quat[i] * self->quat[i];
+ }
+ return PyFloat_FromDouble(sqrt(mag));
+}
+
+static PyObject *Quaternion_getAngle( QuaternionObject * self, void *type )
+{
+ double ang = self->quat[0];
+ ang = 2 * (saacos(ang));
+ ang *= (180 / Py_PI);
+ return PyFloat_FromDouble(ang);
+}
+
+static PyObject *Quaternion_getAxisVec( QuaternionObject * self, void *type )
+{
+ int i;
+ float vec[3];
+ double mag = self->quat[0] * (Py_PI / 180);
+ mag = 2 * (saacos(mag));
+ mag = sin(mag / 2);
+ for(i = 0; i < 3; i++)
+ vec[i] = (float)(self->quat[i + 1] / mag);
+
+ Normalize(vec);
+ //If the axis of rotation is 0,0,0 set it to 1,0,0 - for zero-degree rotations
+ if( EXPP_FloatsAreEqual(vec[0], 0.0f, 10) &&
+ EXPP_FloatsAreEqual(vec[1], 0.0f, 10) &&
+ EXPP_FloatsAreEqual(vec[2], 0.0f, 10) ){
+ vec[0] = 1.0f;
+ }
+ return (PyObject *) newVectorObject(vec, 3, Py_NEW);
+}
+
+
+/*****************************************************************************/
+/* Python attributes get/set structure: */
+/*****************************************************************************/
+static PyGetSetDef Quaternion_getseters[] = {
+ {"w",
+ (getter)Quaternion_getAxis, (setter)Quaternion_setAxis,
+ "Quaternion W value",
+ (void *)'W'},
+ {"x",
+ (getter)Quaternion_getAxis, (setter)Quaternion_setAxis,
+ "Quaternion X axis",
+ (void *)'X'},
+ {"y",
+ (getter)Quaternion_getAxis, (setter)Quaternion_setAxis,
+ "Quaternion Y axis",
+ (void *)'Y'},
+ {"z",
+ (getter)Quaternion_getAxis, (setter)Quaternion_setAxis,
+ "Quaternion Z axis",
+ (void *)'Z'},
+ {"magnitude",
+ (getter)Quaternion_getMagnitude, (setter)NULL,
+ "Size of the quaternion",
+ NULL},
+ {"angle",
+ (getter)Quaternion_getAngle, (setter)NULL,
+ "angle of the quaternion",
+ NULL},
+ {"axis",
+ (getter)Quaternion_getAxisVec, (setter)NULL,
+ "quaternion axis as a vector",
+ NULL},
+ {"wrapped",
+ (getter)Quaternion_getWrapped, (setter)NULL,
+ "True when this wraps blenders internal data",
+ NULL},
+ {NULL,NULL,NULL,NULL,NULL} /* Sentinel */
+};
+
+
//------------------PY_OBECT DEFINITION--------------------------
PyTypeObject quaternion_Type = {
PyObject_HEAD_INIT(NULL) //tp_head
@@ -585,8 +621,8 @@ PyObject_HEAD_INIT(NULL) //tp_head
0, //tp_itemsize
(destructor)Quaternion_dealloc, //tp_dealloc
0, //tp_print
- (getattrfunc)Quaternion_getattr, //tp_getattr
- (setattrfunc) Quaternion_setattr, //tp_setattr
+ 0, //tp_getattr
+ 0, //tp_setattr
0, //tp_compare
(reprfunc) Quaternion_repr, //tp_repr
&Quaternion_NumMethods, //tp_as_number
@@ -606,9 +642,9 @@ PyObject_HEAD_INIT(NULL) //tp_head
0, //tp_weaklistoffset
0, //tp_iter
0, //tp_iternext
- 0, //tp_methods
+ Quaternion_methods, //tp_methods
0, //tp_members
- 0, //tp_getset
+ Quaternion_getseters, //tp_getset
0, //tp_base
0, //tp_dict
0, //tp_descr_get
diff --git a/source/blender/python/api2_2x/vector.c b/source/blender/python/api2_2x/vector.c
index fe28f0fac42..8f2e8991519 100644
--- a/source/blender/python/api2_2x/vector.c
+++ b/source/blender/python/api2_2x/vector.c
@@ -1026,14 +1026,12 @@ static PyObject *Vector_getAxis( VectorObject * self, void *type )
static int Vector_setAxis( VectorObject * self, PyObject * value, void * type )
{
- float param;
+ float param= (float)PyFloat_AsDouble( value );
- if (!PyNumber_Check(value))
+ if (param==-1 && PyErr_Occurred())
return EXPP_ReturnIntError( PyExc_TypeError,
"expected a number for the vector axis" );
- param= (float)PyFloat_AsDouble( value );
-
switch( (long)type ) {
case 'X': /* these are backwards, but that how it works */
self->vec[0]= param;
@@ -1054,13 +1052,6 @@ static int Vector_setAxis( VectorObject * self, PyObject * value, void * type )
self->vec[3]= param;
break;
- default:
- {
- char errstr[1024];
- sprintf( errstr, "undefined type '%d' in Vector_setAxis",
- (int)((long)type & 0xff));
- return EXPP_ReturnIntError( PyExc_RuntimeError, errstr );
- }
}
return 0;
@@ -1160,7 +1151,7 @@ static PyGetSetDef Vector_getseters[] = {
NULL},
{"wrapped",
(getter)Vector_getWrapped, (setter)NULL,
- "Vector Length",
+ "True when this wraps blenders internal data",
NULL},
{NULL,NULL,NULL,NULL,NULL} /* Sentinel */
};
diff --git a/source/blender/python/api2_2x/vector.h b/source/blender/python/api2_2x/vector.h
index 61b50d5f458..898e3947abd 100644
--- a/source/blender/python/api2_2x/vector.h
+++ b/source/blender/python/api2_2x/vector.h
@@ -34,7 +34,7 @@
extern PyTypeObject vector_Type;
-#define VectorObject_Check(v) ((v)->ob_type == &vector_Type)
+#define VectorObject_Check(v) (((PyObject *)v)->ob_type == &vector_Type)
typedef struct {
PyObject_VAR_HEAD