diff options
Diffstat (limited to 'source/blender/python/generic/Mathutils.c')
-rw-r--r-- | source/blender/python/generic/Mathutils.c | 225 |
1 files changed, 148 insertions, 77 deletions
diff --git a/source/blender/python/generic/Mathutils.c b/source/blender/python/generic/Mathutils.c index 3c34a369baf..cd9705236d7 100644 --- a/source/blender/python/generic/Mathutils.c +++ b/source/blender/python/generic/Mathutils.c @@ -1,5 +1,5 @@ /* - * $Id: Mathutils.c 20922 2009-06-16 07:16:51Z campbellbarton $ + * $Id$ * * ***** BEGIN GPL LICENSE BLOCK ***** * @@ -96,7 +96,7 @@ struct PyMethodDef M_Mathutils_methods[] = { #if (PY_VERSION_HEX >= 0x03000000) static struct PyModuleDef M_Mathutils_module_def = { - {}, /* m_base */ + PyModuleDef_HEAD_INIT, "Mathutils", /* m_name */ M_Mathutils_doc, /* m_doc */ 0, /* m_size */ @@ -137,81 +137,12 @@ PyObject *Mathutils_Init(const char *from) PyModule_AddObject( submodule, "Euler", (PyObject *)&euler_Type ); PyModule_AddObject( submodule, "Quaternion", (PyObject *)&quaternion_Type ); + mathutils_matrix_vector_cb_index= Mathutils_RegisterCallback(&mathutils_matrix_vector_cb); + return (submodule); } //-----------------------------METHODS---------------------------- -//----------------column_vector_multiplication (internal)--------- -//COLUMN VECTOR Multiplication (Matrix X Vector) -// [1][2][3] [a] -// [4][5][6] * [b] -// [7][8][9] [c] -//vector/matrix multiplication IS NOT COMMUTATIVE!!!! -PyObject *column_vector_multiplication(MatrixObject * mat, VectorObject* vec) -{ - float vecNew[4], vecCopy[4]; - double dot = 0.0f; - int x, y, z = 0; - - if(mat->rowSize != vec->size){ - if(mat->rowSize == 4 && vec->size != 3){ - PyErr_SetString(PyExc_AttributeError, "matrix * vector: matrix row size and vector size must be the same"); - return NULL; - }else{ - vecCopy[3] = 1.0f; - } - } - - for(x = 0; x < vec->size; x++){ - vecCopy[x] = vec->vec[x]; - } - - for(x = 0; x < mat->rowSize; x++) { - for(y = 0; y < mat->colSize; y++) { - dot += mat->matrix[x][y] * vecCopy[y]; - } - vecNew[z++] = (float)dot; - dot = 0.0f; - } - return newVectorObject(vecNew, vec->size, Py_NEW); -} - -//-----------------row_vector_multiplication (internal)----------- -//ROW VECTOR Multiplication - Vector X Matrix -//[x][y][z] * [1][2][3] -// [4][5][6] -// [7][8][9] -//vector/matrix multiplication IS NOT COMMUTATIVE!!!! -PyObject *row_vector_multiplication(VectorObject* vec, MatrixObject * mat) -{ - float vecNew[4], vecCopy[4]; - double dot = 0.0f; - int x, y, z = 0, vec_size = vec->size; - - if(mat->colSize != vec_size){ - if(mat->rowSize == 4 && vec_size != 3){ - PyErr_SetString(PyExc_AttributeError, "vector * matrix: matrix column size and the vector size must be the same"); - return NULL; - }else{ - vecCopy[3] = 1.0f; - } - } - - for(x = 0; x < vec_size; x++){ - vecCopy[x] = vec->vec[x]; - } - - //muliplication - for(x = 0; x < mat->colSize; x++) { - for(y = 0; y < mat->rowSize; y++) { - dot += mat->matrix[y][x] * vecCopy[y]; - } - vecNew[z++] = (float)dot; - dot = 0.0f; - } - return newVectorObject(vecNew, vec_size, Py_NEW); -} - //-----------------quat_rotation (internal)----------- //This function multiplies a vector/point * quat or vice versa //to rotate the point/vector by the quaternion @@ -226,6 +157,10 @@ PyObject *quat_rotation(PyObject *arg1, PyObject *arg2) quat = (QuaternionObject*)arg1; if(VectorObject_Check(arg2)){ vec = (VectorObject*)arg2; + + if(!Vector_ReadCallback(vec)) + return NULL; + rot[0] = quat->quat[0]*quat->quat[0]*vec->vec[0] + 2*quat->quat[2]*quat->quat[0]*vec->vec[2] - 2*quat->quat[3]*quat->quat[0]*vec->vec[1] + quat->quat[1]*quat->quat[1]*vec->vec[0] + 2*quat->quat[2]*quat->quat[1]*vec->vec[1] + 2*quat->quat[3]*quat->quat[1]*vec->vec[2] - @@ -242,6 +177,10 @@ PyObject *quat_rotation(PyObject *arg1, PyObject *arg2) } }else if(VectorObject_Check(arg1)){ vec = (VectorObject*)arg1; + + if(!Vector_ReadCallback(vec)) + return NULL; + if(QuaternionObject_Check(arg2)){ quat = (QuaternionObject*)arg2; rot[0] = quat->quat[0]*quat->quat[0]*vec->vec[0] + 2*quat->quat[2]*quat->quat[0]*vec->vec[2] - @@ -308,6 +247,9 @@ static PyObject *M_Mathutils_AngleBetweenVecs(PyObject * self, PyObject * args) if(vec1->size != vec2->size) goto AttributeError1; //bad sizes + if(!Vector_ReadCallback(vec1) || !Vector_ReadCallback(vec2)) + return NULL; + //since size is the same.... size = vec1->size; @@ -353,6 +295,9 @@ static PyObject *M_Mathutils_MidpointVecs(PyObject * self, PyObject * args) PyErr_SetString(PyExc_AttributeError, "Mathutils.MidpointVecs(): expects (2) vector objects of the same size\n"); return NULL; } + + if(!Vector_ReadCallback(vec1) || !Vector_ReadCallback(vec2)) + return NULL; for(x = 0; x < vec1->size; x++) { vec[x] = 0.5f * (vec1->vec[x] + vec2->vec[x]); @@ -377,6 +322,10 @@ static PyObject *M_Mathutils_ProjectVecs(PyObject * self, PyObject * args) return NULL; } + if(!Vector_ReadCallback(vec1) || !Vector_ReadCallback(vec2)) + return NULL; + + //since they are the same size... size = vec1->size; @@ -439,6 +388,10 @@ static PyObject *M_Mathutils_RotationMatrix(PyObject * self, PyObject * args) PyErr_SetString(PyExc_AttributeError, "Mathutils.RotationMatrix(): the arbitrary axis must be a 3D vector\n"); return NULL; } + + if(!Vector_ReadCallback(vec)) + return NULL; + } //convert to radians angle = angle * (float) (Py_PI / 180); @@ -538,6 +491,10 @@ static PyObject *M_Mathutils_TranslationMatrix(PyObject * self, VectorObject * v PyErr_SetString(PyExc_TypeError, "Mathutils.TranslationMatrix(): vector must be 3D or 4D\n"); return NULL; } + + if(!Vector_ReadCallback(vec)) + return NULL; + //create a identity matrix and add translation Mat4One((float(*)[4]) mat); mat[12] = vec->vec[0]; @@ -570,6 +527,10 @@ static PyObject *M_Mathutils_ScaleMatrix(PyObject * self, PyObject * args) PyErr_SetString(PyExc_AttributeError, "Mathutils.ScaleMatrix(): please use 2D vectors when scaling in 2D\n"); return NULL; } + + if(!Vector_ReadCallback(vec)) + return NULL; + } if(vec == NULL) { //scaling along axis if(matSize == 2) { @@ -645,6 +606,10 @@ static PyObject *M_Mathutils_OrthoProjectionMatrix(PyObject * self, PyObject * a PyErr_SetString(PyExc_AttributeError, "Mathutils.OrthoProjectionMatrix(): please use 2D vectors when scaling in 2D\n"); return NULL; } + + if(!Vector_ReadCallback(vec)) + return NULL; + } if(vec == NULL) { //ortho projection onto cardinal plane if(((strcmp(plane, "x") == 0) @@ -891,6 +856,9 @@ static PyObject *M_Mathutils_Intersect( PyObject * self, PyObject * args ) return NULL; } + if(!Vector_ReadCallback(vec1) || !Vector_ReadCallback(vec2) || !Vector_ReadCallback(vec3) || !Vector_ReadCallback(ray) || !Vector_ReadCallback(ray_off)) + return NULL; + VECCOPY(v1, vec1->vec); VECCOPY(v2, vec2->vec); VECCOPY(v3, vec3->vec); @@ -959,6 +927,10 @@ static PyObject *M_Mathutils_LineIntersect( PyObject * self, PyObject * args ) PyErr_SetString( PyExc_TypeError,"vectors must be of the same size\n" ); return NULL; } + + if(!Vector_ReadCallback(vec1) || !Vector_ReadCallback(vec2) || !Vector_ReadCallback(vec3) || !Vector_ReadCallback(vec4)) + return NULL; + if( vec1->size == 3 || vec1->size == 2) { int result; @@ -1029,6 +1001,10 @@ static PyObject *M_Mathutils_QuadNormal( PyObject * self, PyObject * args ) PyErr_SetString( PyExc_TypeError, "only 3D vectors\n" ); return NULL; } + + if(!Vector_ReadCallback(vec1) || !Vector_ReadCallback(vec2) || !Vector_ReadCallback(vec3) || !Vector_ReadCallback(vec4)) + return NULL; + VECCOPY(v1, vec1->vec); VECCOPY(v2, vec2->vec); VECCOPY(v3, vec3->vec); @@ -1073,6 +1049,9 @@ static PyObject *M_Mathutils_TriangleNormal( PyObject * self, PyObject * args ) PyErr_SetString( PyExc_TypeError, "only 3D vectors\n" ); return NULL; } + + if(!Vector_ReadCallback(vec1) || !Vector_ReadCallback(vec2) || !Vector_ReadCallback(vec3)) + return NULL; VECCOPY(v1, vec1->vec); VECCOPY(v2, vec2->vec); @@ -1105,6 +1084,9 @@ static PyObject *M_Mathutils_TriangleArea( PyObject * self, PyObject * args ) PyErr_SetString( PyExc_TypeError, "vectors must be of the same size\n" ); return NULL; } + + if(!Vector_ReadCallback(vec1) || !Vector_ReadCallback(vec2) || !Vector_ReadCallback(vec3)) + return NULL; if (vec1->size == 3) { VECCOPY(v1, vec1->vec); @@ -1154,8 +1136,8 @@ int EXPP_FloatsAreEqual(float A, float B, int floatSteps) } /*---------------------- EXPP_VectorsAreEqual ------------------------- Builds on EXPP_FloatsAreEqual to test vectors */ -int EXPP_VectorsAreEqual(float *vecA, float *vecB, int size, int floatSteps){ - +int EXPP_VectorsAreEqual(float *vecA, float *vecB, int size, int floatSteps) +{ int x; for (x=0; x< size; x++){ if (EXPP_FloatsAreEqual(vecA[x], vecB[x], floatSteps) == 0) @@ -1165,6 +1147,95 @@ int EXPP_VectorsAreEqual(float *vecA, float *vecB, int size, int floatSteps){ } +/* Mathutils Callbacks */ + +/* for mathutils internal use only, eventually should re-alloc but to start with we only have a few users */ +Mathutils_Callback *mathutils_callbacks[8] = {NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL}; + +int Mathutils_RegisterCallback(Mathutils_Callback *cb) +{ + int i; + + /* find the first free slot */ + for(i= 0; mathutils_callbacks[i]; i++) { + if(mathutils_callbacks[i]==cb) /* alredy registered? */ + return i; + } + + mathutils_callbacks[i] = cb; + return i; +} + +/* use macros to check for NULL */ +int _Vector_ReadCallback(VectorObject *self) +{ + Mathutils_Callback *cb= mathutils_callbacks[self->cb_type]; + if(cb->get(self->cb_user, self->cb_subtype, self->vec)) { + return 1; + } + else { + PyErr_SetString(PyExc_SystemError, "Vector user has become invalid"); + return 0; + } +} + +int _Vector_WriteCallback(VectorObject *self) +{ + Mathutils_Callback *cb= mathutils_callbacks[self->cb_type]; + if(cb->set(self->cb_user, self->cb_subtype, self->vec)) { + return 1; + } + else { + PyErr_SetString(PyExc_SystemError, "Vector user has become invalid"); + return 0; + } +} -//####################################################################### -//#############################DEPRECATED################################ +int _Vector_ReadIndexCallback(VectorObject *self, int index) +{ + Mathutils_Callback *cb= mathutils_callbacks[self->cb_type]; + if(cb->get_index(self->cb_user, self->cb_subtype, self->vec, index)) { + return 1; + } + else { + PyErr_SetString(PyExc_SystemError, "Vector user has become invalid"); + return 0; + } +} + +int _Vector_WriteIndexCallback(VectorObject *self, int index) +{ + Mathutils_Callback *cb= mathutils_callbacks[self->cb_type]; + if(cb->set_index(self->cb_user, self->cb_subtype, self->vec, index)) { + return 1; + } + else { + PyErr_SetString(PyExc_SystemError, "Vector user has become invalid"); + return 0; + } +} + +/* matrix callbacks */ +int _Matrix_ReadCallback(MatrixObject *self) +{ + Mathutils_Callback *cb= mathutils_callbacks[self->cb_type]; + if(cb->get(self->cb_user, self->cb_subtype, self->contigPtr)) { + return 1; + } + else { + PyErr_SetString(PyExc_SystemError, "Matrix user has become invalid"); + return 0; + } +} + +int _Matrix_WriteCallback(MatrixObject *self) +{ + Mathutils_Callback *cb= mathutils_callbacks[self->cb_type]; + if(cb->set(self->cb_user, self->cb_subtype, self->contigPtr)) { + return 1; + } + else { + PyErr_SetString(PyExc_SystemError, "Matrix user has become invalid"); + return 0; + } +} |