diff options
author | Campbell Barton <ideasman42@gmail.com> | 2009-04-21 11:16:29 +0400 |
---|---|---|
committer | Campbell Barton <ideasman42@gmail.com> | 2009-04-21 11:16:29 +0400 |
commit | 2d054e00b068786996f9154e378e75f436eca239 (patch) | |
tree | bce2e5fcbedd5da38d9775a550271e6fd8b68af8 /source | |
parent | 70dae5f49339a791c1c84d72047cde144e4e2843 (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.c | 22 | ||||
-rw-r--r-- | source/blender/python/api2_2x/Mathutils.c | 20 | ||||
-rw-r--r-- | source/blender/python/api2_2x/euler.c | 147 | ||||
-rw-r--r-- | source/blender/python/api2_2x/quat.c | 248 | ||||
-rw-r--r-- | source/blender/python/api2_2x/vector.c | 15 | ||||
-rw-r--r-- | source/blender/python/api2_2x/vector.h | 2 |
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 |