diff options
-rw-r--r-- | source/blender/python/generic/Mathutils.c | 236 | ||||
-rw-r--r-- | source/blender/python/generic/Mathutils.h | 12 | ||||
-rw-r--r-- | source/blender/python/generic/matrix.c | 181 | ||||
-rw-r--r-- | source/blender/python/generic/matrix.h | 4 | ||||
-rw-r--r-- | source/blender/python/generic/quat.c | 115 | ||||
-rw-r--r-- | source/blender/python/generic/quat.h | 4 | ||||
-rw-r--r-- | source/blender/python/generic/vector.c | 147 |
7 files changed, 166 insertions, 533 deletions
diff --git a/source/blender/python/generic/Mathutils.c b/source/blender/python/generic/Mathutils.c index 1e2e59edbaf..637a42e2aa1 100644 --- a/source/blender/python/generic/Mathutils.c +++ b/source/blender/python/generic/Mathutils.c @@ -41,27 +41,16 @@ static char M_Mathutils_Matrix_doc[] = "() - create a new matrix object from a l static char M_Mathutils_Quaternion_doc[] = "() - create a quaternion from a list or an axis of rotation and an angle"; static char M_Mathutils_Euler_doc[] = "() - create and return a new euler object"; static char M_Mathutils_Rand_doc[] = "() - return a random number"; -static char M_Mathutils_CrossVecs_doc[] = "() - returns a vector perpedicular to the 2 vectors crossed"; -static char M_Mathutils_CopyVec_doc[] = "() - create a copy of vector"; -static char M_Mathutils_DotVecs_doc[] = "() - return the dot product of two vectors"; static char M_Mathutils_AngleBetweenVecs_doc[] = "() - returns the angle between two vectors in degrees"; static char M_Mathutils_MidpointVecs_doc[] = "() - return the vector to the midpoint between two vectors"; -static char M_Mathutils_MatMultVec_doc[] = "() - multiplies a matrix by a column vector"; -static char M_Mathutils_VecMultMat_doc[] = "() - multiplies a row vector by a matrix"; static char M_Mathutils_ProjectVecs_doc[] = "() - returns the projection vector from the projection of vecA onto vecB"; static char M_Mathutils_RotationMatrix_doc[] = "() - construct a rotation matrix from an angle and axis of rotation"; static char M_Mathutils_ScaleMatrix_doc[] = "() - construct a scaling matrix from a scaling factor"; static char M_Mathutils_OrthoProjectionMatrix_doc[] = "() - construct a orthographic projection matrix from a selected plane"; static char M_Mathutils_ShearMatrix_doc[] = "() - construct a shearing matrix from a plane of shear and a shear factor"; -static char M_Mathutils_CopyMat_doc[] = "() - create a copy of a matrix"; static char M_Mathutils_TranslationMatrix_doc[] = "(vec) - create a translation matrix from a vector"; -static char M_Mathutils_CopyQuat_doc[] = "() - copy quatB to quatA"; -static char M_Mathutils_CopyEuler_doc[] = "() - copy eulB to eultA"; -static char M_Mathutils_CrossQuats_doc[] = "() - return the mutliplication of two quaternions"; -static char M_Mathutils_DotQuats_doc[] = "() - return the dot product of two quaternions"; static char M_Mathutils_Slerp_doc[] = "() - returns the interpolation between two quaternions"; static char M_Mathutils_DifferenceQuats_doc[] = "() - return the angular displacment difference between two quats"; -static char M_Mathutils_RotateEuler_doc[] = "() - rotate euler by an axis and angle"; static char M_Mathutils_Intersect_doc[] = "(v1, v2, v3, ray, orig, clip=1) - returns the intersection between a ray and a triangle, if possible, returns None otherwise"; static char M_Mathutils_TriangleArea_doc[] = "(v1, v2, v3) - returns the area size of the 2D or 3D triangle defined"; static char M_Mathutils_TriangleNormal_doc[] = "(v1, v2, v3) - returns the normal of the 3D triangle defined"; @@ -71,30 +60,19 @@ static char M_Mathutils_LineIntersect_doc[] = "(v1, v2, v3, v4) - returns a tupl struct PyMethodDef M_Mathutils_methods[] = { {"Rand", (PyCFunction) M_Mathutils_Rand, METH_VARARGS, M_Mathutils_Rand_doc}, {"Vector", (PyCFunction) M_Mathutils_Vector, METH_VARARGS, M_Mathutils_Vector_doc}, - {"CrossVecs", (PyCFunction) M_Mathutils_CrossVecs, METH_VARARGS, M_Mathutils_CrossVecs_doc}, - {"DotVecs", (PyCFunction) M_Mathutils_DotVecs, METH_VARARGS, M_Mathutils_DotVecs_doc}, {"AngleBetweenVecs", (PyCFunction) M_Mathutils_AngleBetweenVecs, METH_VARARGS, M_Mathutils_AngleBetweenVecs_doc}, {"MidpointVecs", (PyCFunction) M_Mathutils_MidpointVecs, METH_VARARGS, M_Mathutils_MidpointVecs_doc}, - {"VecMultMat", (PyCFunction) M_Mathutils_VecMultMat, METH_VARARGS, M_Mathutils_VecMultMat_doc}, {"ProjectVecs", (PyCFunction) M_Mathutils_ProjectVecs, METH_VARARGS, M_Mathutils_ProjectVecs_doc}, - {"CopyVec", (PyCFunction) M_Mathutils_CopyVec, METH_VARARGS, M_Mathutils_CopyVec_doc}, {"Matrix", (PyCFunction) M_Mathutils_Matrix, METH_VARARGS, M_Mathutils_Matrix_doc}, {"RotationMatrix", (PyCFunction) M_Mathutils_RotationMatrix, METH_VARARGS, M_Mathutils_RotationMatrix_doc}, {"ScaleMatrix", (PyCFunction) M_Mathutils_ScaleMatrix, METH_VARARGS, M_Mathutils_ScaleMatrix_doc}, {"ShearMatrix", (PyCFunction) M_Mathutils_ShearMatrix, METH_VARARGS, M_Mathutils_ShearMatrix_doc}, {"TranslationMatrix", (PyCFunction) M_Mathutils_TranslationMatrix, METH_O, M_Mathutils_TranslationMatrix_doc}, - {"CopyMat", (PyCFunction) M_Mathutils_CopyMat, METH_VARARGS, M_Mathutils_CopyMat_doc}, {"OrthoProjectionMatrix", (PyCFunction) M_Mathutils_OrthoProjectionMatrix, METH_VARARGS, M_Mathutils_OrthoProjectionMatrix_doc}, - {"MatMultVec", (PyCFunction) M_Mathutils_MatMultVec, METH_VARARGS, M_Mathutils_MatMultVec_doc}, {"Quaternion", (PyCFunction) M_Mathutils_Quaternion, METH_VARARGS, M_Mathutils_Quaternion_doc}, - {"CopyQuat", (PyCFunction) M_Mathutils_CopyQuat, METH_VARARGS, M_Mathutils_CopyQuat_doc}, - {"CrossQuats", (PyCFunction) M_Mathutils_CrossQuats, METH_VARARGS, M_Mathutils_CrossQuats_doc}, - {"DotQuats", (PyCFunction) M_Mathutils_DotQuats, METH_VARARGS, M_Mathutils_DotQuats_doc}, {"DifferenceQuats", (PyCFunction) M_Mathutils_DifferenceQuats, METH_VARARGS,M_Mathutils_DifferenceQuats_doc}, {"Slerp", (PyCFunction) M_Mathutils_Slerp, METH_VARARGS, M_Mathutils_Slerp_doc}, {"Euler", (PyCFunction) M_Mathutils_Euler, METH_VARARGS, M_Mathutils_Euler_doc}, - {"CopyEuler", (PyCFunction) M_Mathutils_CopyEuler, METH_VARARGS, M_Mathutils_CopyEuler_doc}, - {"RotateEuler", (PyCFunction) M_Mathutils_RotateEuler, METH_VARARGS, M_Mathutils_RotateEuler_doc}, {"Intersect", ( PyCFunction ) M_Mathutils_Intersect, METH_VARARGS, M_Mathutils_Intersect_doc}, {"TriangleArea", ( PyCFunction ) M_Mathutils_TriangleArea, METH_VARARGS, M_Mathutils_TriangleArea_doc}, {"TriangleNormal", ( PyCFunction ) M_Mathutils_TriangleNormal, METH_VARARGS, M_Mathutils_TriangleNormal_doc}, @@ -356,49 +334,6 @@ PyObject *M_Mathutils_Vector(PyObject * self, PyObject * args) Py_DECREF(listObject); return newVectorObject(vec, size, Py_NEW); } -//----------------------------------Mathutils.CrossVecs() --------------- -//finds perpendicular vector - only 3D is supported -PyObject *M_Mathutils_CrossVecs(PyObject * self, PyObject * args) -{ - PyObject *vecCross = NULL; - VectorObject *vec1 = NULL, *vec2 = NULL; - - if(!PyArg_ParseTuple(args, "O!O!", &vector_Type, &vec1, &vector_Type, &vec2)) { - PyErr_SetString(PyExc_TypeError, "Mathutils.CrossVecs(): expects (2) 3D vector objects\n"); - return NULL; - } - - if(vec1->size != 3 || vec2->size != 3) { - PyErr_SetString(PyExc_AttributeError, "Mathutils.CrossVecs(): expects (2) 3D vector objects\n"); - return NULL; - } - vecCross = newVectorObject(NULL, 3, Py_NEW); - Crossf(((VectorObject*)vecCross)->vec, vec1->vec, vec2->vec); - return vecCross; -} -//----------------------------------Mathutils.DotVec() ------------------- -//calculates the dot product of two vectors -PyObject *M_Mathutils_DotVecs(PyObject * self, PyObject * args) -{ - VectorObject *vec1 = NULL, *vec2 = NULL; - double dot = 0.0f; - int x; - - if(!PyArg_ParseTuple(args, "O!O!", &vector_Type, &vec1, &vector_Type, &vec2)) { - PyErr_SetString(PyExc_TypeError, "Mathutils.DotVecs(): expects (2) vector objects of the same size\n"); - return NULL; - } - - if(vec1->size != vec2->size) { - PyErr_SetString(PyExc_AttributeError, "Mathutils.DotVecs(): expects (2) vector objects of the same size\n"); - return NULL; - } - - for(x = 0; x < vec1->size; x++) { - dot += vec1->vec[x] * vec2->vec[x]; - } - return PyFloat_FromDouble(dot); -} //----------------------------------Mathutils.AngleBetweenVecs() --------- //calculates the angle between 2 vectors PyObject *M_Mathutils_AngleBetweenVecs(PyObject * self, PyObject * args) @@ -1100,39 +1035,7 @@ PyObject *M_Mathutils_Quaternion(PyObject * self, PyObject * args) Py_DECREF(listObject); return newQuaternionObject(quat, Py_NEW); } -//----------------------------------Mathutils.CrossQuats() ---------------- -//quaternion multiplication - associate not commutative -PyObject *M_Mathutils_CrossQuats(PyObject * self, PyObject * args) -{ - QuaternionObject *quatU = NULL, *quatV = NULL; - float quat[4]; - - if(!PyArg_ParseTuple(args, "O!O!", &quaternion_Type, &quatU, &quaternion_Type, &quatV)) { - PyErr_SetString(PyExc_TypeError,"Mathutils.CrossQuats(): expected Quaternion types"); - return NULL; - } - QuatMul(quat, quatU->quat, quatV->quat); - - return newQuaternionObject(quat, Py_NEW); -} -//----------------------------------Mathutils.DotQuats() ---------------- -//returns the dot product of 2 quaternions -PyObject *M_Mathutils_DotQuats(PyObject * self, PyObject * args) -{ - QuaternionObject *quatU = NULL, *quatV = NULL; - double dot = 0.0f; - int x; - - if(!PyArg_ParseTuple(args, "O!O!", &quaternion_Type, &quatU, &quaternion_Type, &quatV)) { - PyErr_SetString(PyExc_TypeError, "Mathutils.DotQuats(): expected Quaternion types"); - return NULL; - } - for(x = 0; x < 4; x++) { - dot += quatU->quat[x] * quatV->quat[x]; - } - return PyFloat_FromDouble(dot); -} //----------------------------------Mathutils.DifferenceQuats() --------- //returns the difference between 2 quaternions PyObject *M_Mathutils_DifferenceQuats(PyObject * self, PyObject * args) @@ -1533,145 +1436,6 @@ PyObject *M_Mathutils_TriangleArea( PyObject * self, PyObject * args ) return NULL; } } -//#############################DEPRECATED################################ -//####################################################################### -//----------------------------------Mathutils.CopyMat() ----------------- -//copies a matrix into a new matrix -PyObject *M_Mathutils_CopyMat(PyObject * self, PyObject * args) -{ - PyObject *matrix = NULL; - static char warning = 1; - - if( warning ) { - printf("Mathutils.CopyMat(): deprecated :use Mathutils.Matrix() to copy matrices\n"); - --warning; - } - - matrix = M_Mathutils_Matrix(self, args); - if(matrix == NULL) - return NULL; //error string already set if we get here - else - return matrix; -} -//----------------------------------Mathutils.CopyVec() ----------------- -//makes a new vector that is a copy of the input -PyObject *M_Mathutils_CopyVec(PyObject * self, PyObject * args) -{ - PyObject *vec = NULL; - static char warning = 1; - - if( warning ) { - printf("Mathutils.CopyVec(): Deprecated: use Mathutils.Vector() to copy vectors\n"); - --warning; - } - - vec = M_Mathutils_Vector(self, args); - if(vec == NULL) - return NULL; //error string already set if we get here - else - return vec; -} -//----------------------------------Mathutils.CopyQuat() -------------- -//Copies a quaternion to a new quat -PyObject *M_Mathutils_CopyQuat(PyObject * self, PyObject * args) -{ - PyObject *quat = NULL; - static char warning = 1; - - if( warning ) { - printf("Mathutils.CopyQuat(): Deprecated: use Mathutils.Quaternion() to copy vectors\n"); - --warning; - } - - quat = M_Mathutils_Quaternion(self, args); - if(quat == NULL) - return NULL; //error string already set if we get here - else - return quat; -} -//----------------------------------Mathutils.CopyEuler() --------------- -//copies a euler to a new euler -PyObject *M_Mathutils_CopyEuler(PyObject * self, PyObject * args) -{ - PyObject *eul = NULL; - static char warning = 1; - - if( warning ) { - printf("Mathutils.CopyEuler(): deprecated:use Mathutils.Euler() to copy vectors\n"); - --warning; - } - - eul = M_Mathutils_Euler(self, args); - if(eul == NULL) - return NULL; //error string already set if we get here - else - return eul; -} -//----------------------------------Mathutils.RotateEuler() ------------ -//rotates a euler a certain amount and returns the result -//should return a unique euler rotation (i.e. no 720 degree pitches :) -PyObject *M_Mathutils_RotateEuler(PyObject * self, PyObject * args) -{ - EulerObject *Eul = NULL; - float angle; - char *axis; - static char warning = 1; - - if( warning ) { - printf("Mathutils.RotateEuler(): Deprecated:use Euler.rotate() to rotate a euler\n"); - --warning; - } - - if(!PyArg_ParseTuple(args, "O!fs", &euler_Type, &Eul, &angle, &axis)) { - PyErr_SetString(PyExc_TypeError, "Mathutils.RotateEuler(): expected euler type & float & string"); - return NULL; - } - - Euler_Rotate(Eul, Py_BuildValue("fs", angle, axis)); - Py_RETURN_NONE; -} -//----------------------------------Mathutils.MatMultVec() -------------- -//COLUMN VECTOR Multiplication (Matrix X Vector) -PyObject *M_Mathutils_MatMultVec(PyObject * self, PyObject * args) -{ - MatrixObject *mat = NULL; - VectorObject *vec = NULL; - static char warning = 1; - - if( warning ) { - printf("Mathutils.MatMultVec(): Deprecated: use matrix * vec to perform column vector multiplication\n"); - --warning; - } - - //get pyObjects - if(!PyArg_ParseTuple(args, "O!O!", &matrix_Type, &mat, &vector_Type, &vec)) { - PyErr_SetString(PyExc_TypeError, "Mathutils.MatMultVec(): MatMultVec() expects a matrix and a vector object - in that order\n"); - return NULL; - } - - return column_vector_multiplication(mat, vec); -} -//----------------------------------Mathutils.VecMultMat() --------------- -//ROW VECTOR Multiplication - Vector X Matrix -PyObject *M_Mathutils_VecMultMat(PyObject * self, PyObject * args) -{ - MatrixObject *mat = NULL; - VectorObject *vec = NULL; - static char warning = 1; - - if( warning ) { - printf("Mathutils.VecMultMat(): Deprecated: use vec * matrix to perform row vector multiplication\n"); - --warning; - } - - //get pyObjects - if(!PyArg_ParseTuple(args, "O!O!", &vector_Type, &vec, &matrix_Type, &mat)) { - PyErr_SetString(PyExc_TypeError, "Mathutils.VecMultMat(): VecMultMat() expects a vector and matrix object - in that order\n"); - return NULL; - } - - return row_vector_multiplication(vec, mat); -} /* Utility functions */ diff --git a/source/blender/python/generic/Mathutils.h b/source/blender/python/generic/Mathutils.h index 173922fe09a..af984c58db8 100644 --- a/source/blender/python/generic/Mathutils.h +++ b/source/blender/python/generic/Mathutils.h @@ -64,18 +64,6 @@ PyObject *M_Mathutils_TriangleArea( PyObject * self, PyObject * args ); PyObject *M_Mathutils_TriangleNormal( PyObject * self, PyObject * args ); PyObject *M_Mathutils_QuadNormal( PyObject * self, PyObject * args ); PyObject *M_Mathutils_LineIntersect( PyObject * self, PyObject * args ); -//DEPRECATED -PyObject *M_Mathutils_CopyMat(PyObject * self, PyObject * args); -PyObject *M_Mathutils_CopyVec(PyObject * self, PyObject * args); -PyObject *M_Mathutils_CopyQuat(PyObject * self, PyObject * args); -PyObject *M_Mathutils_CopyEuler(PyObject * self, PyObject * args); -PyObject *M_Mathutils_RotateEuler(PyObject * self, PyObject * args); -PyObject *M_Mathutils_MatMultVec(PyObject * self, PyObject * args); -PyObject *M_Mathutils_VecMultMat(PyObject * self, PyObject * args); -PyObject *M_Mathutils_CrossVecs(PyObject * self, PyObject * args); -PyObject *M_Mathutils_DotVecs(PyObject * self, PyObject * args); -PyObject *M_Mathutils_CrossQuats(PyObject * self, PyObject * args); -PyObject *M_Mathutils_DotQuats(PyObject * self, PyObject * args); int EXPP_FloatsAreEqual(float A, float B, int floatSteps); int EXPP_VectorsAreEqual(float *vecA, float *vecB, int size, int floatSteps); diff --git a/source/blender/python/generic/matrix.c b/source/blender/python/generic/matrix.c index 16c72d69dde..4b2c9d4a8a7 100644 --- a/source/blender/python/generic/matrix.c +++ b/source/blender/python/generic/matrix.c @@ -387,7 +387,6 @@ PyObject *Matrix_copy(MatrixObject * self) /*free the py_object*/ static void Matrix_dealloc(MatrixObject * self) { - Py_XDECREF(self->coerced_object); PyMem_Free(self->matrix); /*only free py_data*/ if(self->data.py_data){ @@ -395,35 +394,7 @@ static void Matrix_dealloc(MatrixObject * self) } PyObject_DEL(self); } -/*----------------------------getattr()(internal) ----------------*/ -/*object.attribute access (get)*/ -static PyObject *Matrix_getattr(MatrixObject * self, char *name) -{ - if(STREQ(name, "rowSize")) { - return PyLong_FromLong((long) self->rowSize); - } else if(STREQ(name, "colSize")) { - return PyLong_FromLong((long) self->colSize); - } - if(STREQ(name, "wrapped")){ - if(self->wrapped == Py_WRAP) - Py_RETURN_TRUE; - else - Py_RETURN_FALSE; - } -#if 0 //XXX - return Py_FindMethod(Matrix_methods, (PyObject *) self, name); -#else - PyErr_SetString(PyExc_AttributeError, "blender 2.5 is not finished yet"); - return NULL; -#endif -} -/*----------------------------setattr()(internal) ----------------*/ -/*object.attribute access (set)*/ -static int Matrix_setattr(MatrixObject * self, char *name, PyObject * v) -{ - /* This is not supported. */ - return (-1); -} + /*----------------------------print object (internal)-------------*/ /*print the object to screen*/ static PyObject *Matrix_repr(MatrixObject * self) @@ -672,7 +643,7 @@ static PyObject *Matrix_add(PyObject * m1, PyObject * m2) mat1 = (MatrixObject*)m1; mat2 = (MatrixObject*)m2; - if(mat1->coerced_object || mat2->coerced_object){ + if(!MatrixObject_Check(m1) || !MatrixObject_Check(m2)) { PyErr_SetString(PyExc_AttributeError, "Matrix addition: arguments not valid for this operation...."); return NULL; } @@ -701,7 +672,7 @@ static PyObject *Matrix_sub(PyObject * m1, PyObject * m2) mat1 = (MatrixObject*)m1; mat2 = (MatrixObject*)m2; - if(mat1->coerced_object || mat2->coerced_object){ + if(!MatrixObject_Check(m1) || !MatrixObject_Check(m2)) { PyErr_SetString(PyExc_AttributeError, "Matrix addition: arguments not valid for this operation...."); return NULL; } @@ -728,22 +699,31 @@ static PyObject *Matrix_mul(PyObject * m1, PyObject * m2) 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f}; double dot = 0.0f; MatrixObject *mat1 = NULL, *mat2 = NULL; - PyObject *f = NULL; - mat1 = (MatrixObject*)m1; - mat2 = (MatrixObject*)m2; + if(MatrixObject_Check(m1)) mat1 = (MatrixObject*)m1; + if(MatrixObject_Check(m2)) mat2 = (MatrixObject*)m2; - if(mat1->coerced_object){ - if (PyFloat_Check(mat1->coerced_object) || - PyLong_Check(mat1->coerced_object)){ /*FLOAT/INT * MATRIX*/ - f = PyNumber_Float(mat1->coerced_object); - if(f == NULL) { /*parsed item not a number*/ - PyErr_SetString(PyExc_TypeError, "Matrix multiplication: arguments not acceptable for this operation"); - return NULL; + if(mat1 && mat2) { /*MATRIX * MATRIX*/ + if(mat1->colSize != mat2->rowSize){ + PyErr_SetString(PyExc_AttributeError,"Matrix multiplication: matrix A rowsize must equal matrix B colsize"); + return NULL; + } + for(x = 0; x < mat1->rowSize; x++) { + for(y = 0; y < mat2->colSize; y++) { + for(z = 0; z < mat1->colSize; z++) { + dot += (mat1->matrix[x][z] * mat2->matrix[z][y]); + } + mat[((x * mat1->rowSize) + y)] = (float)dot; + dot = 0.0f; } - - scalar = (float)PyFloat_AS_DOUBLE(f); - Py_DECREF(f); + } + + return newMatrixObject(mat, mat1->rowSize, mat2->colSize, Py_NEW); + } + + if(mat1==NULL){ + scalar=PyFloat_AsDouble(m1); // may not be a float... + if ((scalar == -1.0 && PyErr_Occurred())==0) { /*FLOAT/INT * MATRIX, this line annoys theeth, lets see if he finds it */ for(x = 0; x < mat2->rowSize; x++) { for(y = 0; y < mat2->colSize; y++) { mat[((x * mat2->colSize) + y)] = scalar * mat2->matrix[x][y]; @@ -751,22 +731,18 @@ static PyObject *Matrix_mul(PyObject * m1, PyObject * m2) } return newMatrixObject(mat, mat2->rowSize, mat2->colSize, Py_NEW); } - }else{ - if(mat2->coerced_object){ - /* MATRIX * VECTOR operation is now being done by vector */ - /*if(VectorObject_Check(mat2->coerced_object)){ - vec = (VectorObject*)mat2->coerced_object; - return column_vector_multiplication(mat1, vec); - }else */ - if (PyFloat_Check(mat2->coerced_object) || PyLong_Check(mat2->coerced_object)){ /*MATRIX * FLOAT/INT*/ - f = PyNumber_Float(mat2->coerced_object); - if(f == NULL) { /*parsed item not a number*/ - PyErr_SetString(PyExc_TypeError, "Matrix multiplication: arguments not acceptable for this operation\n"); - return NULL; - } - - scalar = (float)PyFloat_AS_DOUBLE(f); - Py_DECREF(f); + + PyErr_SetString(PyExc_TypeError, "Matrix multiplication: arguments not acceptable for this operation"); + return NULL; + } + else /* if(mat1) { */ { + + if(VectorObject_Check(m2)) { /* MATRIX*VECTOR */ + return column_vector_multiplication(mat1, (VectorObject *)m2); + } + else { + scalar= PyFloat_AsDouble(m2); + if ((scalar == -1.0 && PyErr_Occurred())==0) { /* MATRIX*FLOAT/INT */ for(x = 0; x < mat1->rowSize; x++) { for(y = 0; y < mat1->colSize; y++) { mat[((x * mat1->colSize) + y)] = scalar * mat1->matrix[x][y]; @@ -774,22 +750,9 @@ static PyObject *Matrix_mul(PyObject * m1, PyObject * m2) } return newMatrixObject(mat, mat1->rowSize, mat1->colSize, Py_NEW); } - }else{ /*MATRIX * MATRIX*/ - if(mat1->colSize != mat2->rowSize){ - PyErr_SetString(PyExc_AttributeError,"Matrix multiplication: matrix A rowsize must equal matrix B colsize"); - return NULL; - } - for(x = 0; x < mat1->rowSize; x++) { - for(y = 0; y < mat2->colSize; y++) { - for(z = 0; z < mat1->colSize; z++) { - dot += (mat1->matrix[x][z] * mat2->matrix[z][y]); - } - mat[((x * mat1->rowSize) + y)] = (float)dot; - dot = 0.0f; - } - } - return newMatrixObject(mat, mat1->rowSize, mat2->colSize, Py_NEW); } + PyErr_SetString(PyExc_TypeError, "Matrix multiplication: arguments not acceptable for this operation"); + return NULL; } PyErr_SetString(PyExc_TypeError, "Matrix multiplication: arguments not acceptable for this operation\n"); @@ -799,29 +762,7 @@ static PyObject* Matrix_inv(MatrixObject *self) { return Matrix_Invert(self); } -/*------------------------coerce(obj, obj)----------------------- - coercion of unknown types to type MatrixObject for numeric protocols. - - Coercion() is called whenever a math operation has 2 operands that - it doesn't understand how to evaluate. 2+Matrix for example. We want to - evaluate some of these operations like: (vector * 2), however, for math - to proceed, the unknown operand must be cast to a type that python math will - understand. (e.g. in the case above case, 2 must be cast to a vector and - then call vector.multiply(vector, scalar_cast_as_vector)*/ -static int Matrix_coerce(PyObject ** m1, PyObject ** m2) -{ - if(VectorObject_Check(*m2) || PyFloat_Check(*m2) || PyLong_Check(*m2)) { - PyObject *coerced = (PyObject *)(*m2); - Py_INCREF(coerced); - *m2 = newMatrixObject(NULL,3,3,Py_NEW); - ((MatrixObject*)*m2)->coerced_object = coerced; - Py_INCREF (*m1); - return 0; - } - PyErr_SetString(PyExc_TypeError, "matrix.coerce(): unknown operand - can't coerce for numeric protocols"); - return -1; -} /*-----------------PROTOCOL DECLARATIONS--------------------------*/ static PySequenceMethods Matrix_SeqMethods = { (inquiry) Matrix_len, /* sq_length */ @@ -850,17 +791,42 @@ static PyNumberMethods Matrix_NumMethods = { (binaryfunc) 0, /* __and__ */ (binaryfunc) 0, /* __xor__ */ (binaryfunc) 0, /* __or__ */ -#if 0 // XXX 2.5 - (coercion) Matrix_coerce, /* __coerce__ */ -#else - 0, -#endif + /*(coercion)*/ 0, /* __coerce__ */ (unaryfunc) 0, /* __int__ */ (unaryfunc) 0, /* __long__ */ (unaryfunc) 0, /* __float__ */ (unaryfunc) 0, /* __oct__ */ (unaryfunc) 0, /* __hex__ */ }; + +static PyObject *Matrix_getRowSize( MatrixObject * self, void *type ) +{ + return PyLong_FromLong((long) self->rowSize); +} + +static PyObject *Matrix_getColSize( MatrixObject * self, void *type ) +{ + return PyLong_FromLong((long) self->colSize); +} + +static PyObject *Matrix_getWrapped( MatrixObject * self, void *type ) +{ + if (self->wrapped == Py_WRAP) + Py_RETURN_TRUE; + else + Py_RETURN_FALSE; +} + +/*****************************************************************************/ +/* Python attributes get/set structure: */ +/*****************************************************************************/ +static PyGetSetDef Matrix_getseters[] = { + {"rowSize", (getter)Matrix_getRowSize, (setter)NULL, "", NULL}, + {"colSize", (getter)Matrix_getColSize, (setter)NULL, "", NULL}, + {"wrapped", (getter)Matrix_getWrapped, (setter)NULL, "", NULL}, + {NULL,NULL,NULL,NULL,NULL} /* Sentinel */ +}; + /*------------------PY_OBECT DEFINITION--------------------------*/ PyTypeObject matrix_Type = { #if (PY_VERSION_HEX >= 0x02060000) @@ -875,8 +841,8 @@ PyTypeObject matrix_Type = { 0, /*tp_itemsize*/ (destructor)Matrix_dealloc, /*tp_dealloc*/ 0, /*tp_print*/ - (getattrfunc)Matrix_getattr, /*tp_getattr*/ - (setattrfunc) Matrix_setattr, /*tp_setattr*/ + 0, /*tp_getattr*/ + 0, /*tp_setattr*/ 0, /*tp_compare*/ (reprfunc) Matrix_repr, /*tp_repr*/ &Matrix_NumMethods, /*tp_as_number*/ @@ -896,9 +862,9 @@ PyTypeObject matrix_Type = { 0, /*tp_weaklistoffset*/ 0, /*tp_iter*/ 0, /*tp_iternext*/ - 0, /*tp_methods*/ + Matrix_methods, /*tp_methods*/ 0, /*tp_members*/ - 0, /*tp_getset*/ + Matrix_getseters, /*tp_getset*/ 0, /*tp_base*/ 0, /*tp_dict*/ 0, /*tp_descr_get*/ @@ -949,7 +915,6 @@ PyObject *newMatrixObject(float *mat, int rowSize, int colSize, int type) self->data.py_data = NULL; self->rowSize = rowSize; self->colSize = colSize; - self->coerced_object = NULL; if(type == Py_WRAP){ self->data.blend_data = mat; diff --git a/source/blender/python/generic/matrix.h b/source/blender/python/generic/matrix.h index fd51d99c455..4658f4b5f6c 100644 --- a/source/blender/python/generic/matrix.h +++ b/source/blender/python/generic/matrix.h @@ -48,11 +48,7 @@ typedef struct _Matrix { int rowSize; int colSize; int wrapped; /*is wrapped data?*/ - PyObject *coerced_object; } MatrixObject; -/*coerced_object is a pointer to the object that it was -coerced from when a dummy vector needs to be created from -the coerce() function for numeric protocol operations*/ /*struct data contains a pointer to the actual data that the object uses. It can use either PyMem allocated data (which will diff --git a/source/blender/python/generic/quat.c b/source/blender/python/generic/quat.c index ca703f12907..c3c9e28c520 100644 --- a/source/blender/python/generic/quat.c +++ b/source/blender/python/generic/quat.c @@ -208,7 +208,6 @@ PyObject *Quaternion_copy(QuaternionObject * self) //free the py_object static void Quaternion_dealloc(QuaternionObject * self) { - Py_XDECREF(self->coerced_object); //only free py_data if(self->data.py_data){ PyMem_Free(self->data.py_data); @@ -377,13 +376,14 @@ static PyObject *Quaternion_add(PyObject * q1, PyObject * q2) float quat[4]; QuaternionObject *quat1 = NULL, *quat2 = NULL; - quat1 = (QuaternionObject*)q1; - quat2 = (QuaternionObject*)q2; - - if(quat1->coerced_object || quat2->coerced_object){ + if(!QuaternionObject_Check(q1) || !QuaternionObject_Check(q2)) { PyErr_SetString(PyExc_AttributeError, "Quaternion addition: arguments not valid for this operation....\n"); return NULL; } + + quat1 = (QuaternionObject*)q1; + quat2 = (QuaternionObject*)q2; + for(x = 0; x < 4; x++) { quat[x] = quat1->quat[x] + quat2->quat[x]; } @@ -398,13 +398,14 @@ static PyObject *Quaternion_sub(PyObject * q1, PyObject * q2) float quat[4]; QuaternionObject *quat1 = NULL, *quat2 = NULL; - quat1 = (QuaternionObject*)q1; - quat2 = (QuaternionObject*)q2; - - if(quat1->coerced_object || quat2->coerced_object){ + if(!QuaternionObject_Check(q1) || !QuaternionObject_Check(q2)) { PyErr_SetString(PyExc_AttributeError, "Quaternion addition: arguments not valid for this operation....\n"); return NULL; } + + quat1 = (QuaternionObject*)q1; + quat2 = (QuaternionObject*)q2; + for(x = 0; x < 4; x++) { quat[x] = quat1->quat[x] - quat2->quat[x]; } @@ -419,86 +420,53 @@ static PyObject *Quaternion_mul(PyObject * q1, PyObject * q2) float quat[4], scalar; double dot = 0.0f; QuaternionObject *quat1 = NULL, *quat2 = NULL; - PyObject *f = NULL; VectorObject *vec = NULL; quat1 = (QuaternionObject*)q1; quat2 = (QuaternionObject*)q2; - if(quat1->coerced_object){ - if (PyFloat_Check(quat1->coerced_object) || - PyLong_Check(quat1->coerced_object)){ // FLOAT/INT * QUAT - f = PyNumber_Float(quat1->coerced_object); - if(f == NULL) { // parsed item not a number - PyErr_SetString(PyExc_TypeError, "Quaternion multiplication: arguments not acceptable for this operation\n"); - return NULL; - } - - scalar = (float)PyFloat_AS_DOUBLE(f); - Py_DECREF(f); + if(QuaternionObject_Check(q1) && QuaternionObject_Check(q2)) { /* QUAT*QUAT (dot product) */ + for(x = 0; x < 4; x++) { + dot += quat1->quat[x] * quat1->quat[x]; + } + return PyFloat_FromDouble(dot); + } + + /* the only case this can happen (for a supported type is "FLOAT*QUAT" ) */ + if(!QuaternionObject_Check(q1)) { + scalar= PyFloat_AsDouble(q1); + if ((scalar == -1.0 && PyErr_Occurred())==0) { /* FLOAT*QUAT */ for(x = 0; x < 4; x++) { quat[x] = quat2->quat[x] * scalar; } return newQuaternionObject(quat, Py_NEW); } - }else{ - if(quat2->coerced_object){ - if (PyFloat_Check(quat2->coerced_object) || - PyLong_Check(quat2->coerced_object)){ // QUAT * FLOAT/INT - f = PyNumber_Float(quat2->coerced_object); - if(f == NULL) { // parsed item not a number - PyErr_SetString(PyExc_TypeError, "Quaternion multiplication: arguments not acceptable for this operation\n"); - return NULL; - } - - scalar = (float)PyFloat_AS_DOUBLE(f); - Py_DECREF(f); - for(x = 0; x < 4; x++) { - quat[x] = quat1->quat[x] * scalar; - } - return newQuaternionObject(quat, Py_NEW); - }else if(VectorObject_Check(quat2->coerced_object)){ //QUAT * VEC - vec = (VectorObject*)quat2->coerced_object; - if(vec->size != 3){ - PyErr_SetString(PyExc_TypeError, "Quaternion multiplication: only 3D vector rotations currently supported\n"); - return NULL; - } - return quat_rotation((PyObject*)quat1, (PyObject*)vec); + PyErr_SetString(PyExc_TypeError, "Quaternion multiplication: val * quat, val is not an acceptable type"); + return NULL; + } + else { /* QUAT*SOMETHING */ + if(VectorObject_Check(q2)){ /* QUAT*VEC */ + vec = (VectorObject*)q2; + if(vec->size != 3){ + PyErr_SetString(PyExc_TypeError, "Quaternion multiplication: only 3D vector rotations currently supported\n"); + return NULL; } - }else{ //QUAT * QUAT (dot product) + return quat_rotation((PyObject*)quat1, (PyObject*)vec); + } + + scalar= PyFloat_AsDouble(q2); + if ((scalar == -1.0 && PyErr_Occurred())==0) { /* QUAT*FLOAT */ for(x = 0; x < 4; x++) { - dot += quat1->quat[x] * quat1->quat[x]; + quat[x] = quat1->quat[x] * scalar; } - return PyFloat_FromDouble(dot); + return newQuaternionObject(quat, Py_NEW); } } - + PyErr_SetString(PyExc_TypeError, "Quaternion multiplication: arguments not acceptable for this operation\n"); return NULL; } -//------------------------coerce(obj, obj)----------------------- -//coercion of unknown types to type QuaternionObject for numeric protocols -/*Coercion() is called whenever a math operation has 2 operands that - it doesn't understand how to evaluate. 2+Matrix for example. We want to - evaluate some of these operations like: (vector * 2), however, for math - to proceed, the unknown operand must be cast to a type that python math will - understand. (e.g. in the case above case, 2 must be cast to a vector and - then call vector.multiply(vector, scalar_cast_as_vector)*/ -static int Quaternion_coerce(PyObject ** q1, PyObject ** q2) -{ - if(VectorObject_Check(*q2) || PyFloat_Check(*q2) || PyLong_Check(*q2)) { - PyObject *coerced = (PyObject *)(*q2); - Py_INCREF(coerced); - - *q2 = newQuaternionObject(NULL,Py_NEW); - ((QuaternionObject*)*q2)->coerced_object = coerced; - Py_INCREF (*q1); - return 0; - } - PyErr_SetString(PyExc_TypeError, "quaternion.coerce(): unknown operand - can't coerce for numeric protocols"); - return -1; -} //-----------------PROTOCOL DECLARATIONS-------------------------- static PySequenceMethods Quaternion_SeqMethods = { (inquiry) Quaternion_len, /* sq_length */ @@ -527,11 +495,7 @@ static PyNumberMethods Quaternion_NumMethods = { (binaryfunc) 0, /* __and__ */ (binaryfunc) 0, /* __xor__ */ (binaryfunc) 0, /* __or__ */ -#if 0 //XXX 2.5 - (coercion) Quaternion_coerce, /* __coerce__ */ -#else - 0, -#endif + /*(coercion)*/ 0, /* __coerce__ */ (unaryfunc) 0, /* __int__ */ (unaryfunc) 0, /* __long__ */ (unaryfunc) 0, /* __float__ */ @@ -740,7 +704,6 @@ PyObject *newQuaternionObject(float *quat, int type) self = PyObject_NEW(QuaternionObject, &quaternion_Type); self->data.blend_data = NULL; self->data.py_data = NULL; - self->coerced_object = NULL; if(type == Py_WRAP){ self->data.blend_data = quat; diff --git a/source/blender/python/generic/quat.h b/source/blender/python/generic/quat.h index 8a4602c1d8e..8887b147705 100644 --- a/source/blender/python/generic/quat.h +++ b/source/blender/python/generic/quat.h @@ -46,11 +46,7 @@ typedef struct { }data; float *quat; //1D array of data (alias) int wrapped; //is wrapped data? - PyObject *coerced_object; } QuaternionObject; -/*coerced_object is a pointer to the object that it was -coerced from when a dummy vector needs to be created from -the coerce() function for numeric protocol operations*/ /*struct data contains a pointer to the actual data that the object uses. It can use either PyMem allocated data (which will diff --git a/source/blender/python/generic/vector.c b/source/blender/python/generic/vector.c index 86ce5c21217..e2009d9974e 100644 --- a/source/blender/python/generic/vector.c +++ b/source/blender/python/generic/vector.c @@ -428,8 +428,8 @@ static PyObject *Vector_item(VectorObject * self, int i) sequence accessor (set)*/ static int Vector_ass_item(VectorObject * self, int i, PyObject * ob) { - - if(!(PyNumber_Check(ob))) { /* parsed item not a number */ + float scalar= (float)PyFloat_AsDouble(ob); + if(scalar==-1.0f && PyErr_Occurred()) { /* parsed item not a number */ PyErr_SetString(PyExc_TypeError, "vector[index] = x: index argument not a number\n"); return -1; } @@ -438,7 +438,7 @@ static int Vector_ass_item(VectorObject * self, int i, PyObject * ob) PyErr_SetString(PyExc_IndexError, "vector[index] = x: assignment index out of range\n"); return -1; } - self->vec[i] = (float)PyFloat_AsDouble(ob); + self->vec[i] = scalar; return 0; } @@ -468,7 +468,7 @@ static int Vector_ass_slice(VectorObject * self, int begin, int end, PyObject * seq) { int i, y, size = 0; - float vec[4]; + float vec[4], scalar; PyObject *v; CLAMP(begin, 0, self->size); @@ -489,13 +489,14 @@ static int Vector_ass_slice(VectorObject * self, int begin, int end, return -1; } - if(!PyNumber_Check(v)) { /* parsed item not a number */ + scalar= (float)PyFloat_AsDouble(v); + if(scalar==-1.0f && PyErr_Occurred()) { /* parsed item not a number */ Py_DECREF(v); PyErr_SetString(PyExc_TypeError, "vector[begin:end] = []: sequence argument not a number\n"); return -1; } - vec[i] = (float)PyFloat_AsDouble(v); + vec[i] = scalar; Py_DECREF(v); } /*parsed well - now set in vector*/ @@ -628,6 +629,7 @@ static PyObject *Vector_isub(PyObject * v1, PyObject * v2) static PyObject *Vector_mul(PyObject * v1, PyObject * v2) { VectorObject *vec1 = NULL, *vec2 = NULL; + float scalar; if VectorObject_Check(v1) vec1= (VectorObject *)v1; @@ -658,23 +660,9 @@ static PyObject *Vector_mul(PyObject * v1, PyObject * v2) v2= v1; } - if (PyNumber_Check(v2)) { - /* VEC * NUM */ - int i; - float vec[4]; - float scalar = (float)PyFloat_AsDouble( v2 ); - - for(i = 0; i < vec1->size; i++) { - vec[i] = vec1->vec[i] * scalar; - } - return newVectorObject(vec, vec1->size, Py_NEW); - - } else if (MatrixObject_Check(v2)) { + if (MatrixObject_Check(v2)) { /* VEC * MATRIX */ - if (v1==v2) /* mat*vec, we have swapped the order */ - return column_vector_multiplication((MatrixObject*)v2, vec1); - else /* vec*mat */ - return row_vector_multiplication(vec1, (MatrixObject*)v2); + return row_vector_multiplication(vec1, (MatrixObject*)v2); } else if (QuaternionObject_Check(v2)) { QuaternionObject *quat = (QuaternionObject*)v2; if(vec1->size != 3) { @@ -683,6 +671,16 @@ static PyObject *Vector_mul(PyObject * v1, PyObject * v2) } return quat_rotation((PyObject*)vec1, (PyObject*)quat); } + else if (((scalar= PyFloat_AsDouble(v2)) == -1.0 && PyErr_Occurred())==0) { /* VEC*FLOAT */ + int i; + float vec[4]; + + for(i = 0; i < vec1->size; i++) { + vec[i] = vec1->vec[i] * scalar; + } + return newVectorObject(vec, vec1->size, Py_NEW); + + } PyErr_SetString(PyExc_TypeError, "Vector multiplication: arguments not acceptable for this operation\n"); return NULL; @@ -694,21 +692,11 @@ static PyObject *Vector_imul(PyObject * v1, PyObject * v2) { VectorObject *vec = (VectorObject *)v1; int i; + float scalar; /* only support vec*=float and vec*=mat vec*=vec result is a float so that wont work */ - if (PyNumber_Check(v2)) { - /* VEC * NUM */ - float scalar = (float)PyFloat_AsDouble( v2 ); - - for(i = 0; i < vec->size; i++) { - vec->vec[i] *= scalar; - } - - Py_INCREF( v1 ); - return v1; - - } else if (MatrixObject_Check(v2)) { + if (MatrixObject_Check(v2)) { float vecCopy[4]; int x,y, size = vec->size; MatrixObject *mat= (MatrixObject*)v2; @@ -739,6 +727,17 @@ static PyObject *Vector_imul(PyObject * v1, PyObject * v2) Py_INCREF( v1 ); return v1; } + else if (((scalar= PyFloat_AsDouble(v2)) == -1.0 && PyErr_Occurred())==0) { /* VEC*=FLOAT */ + + for(i = 0; i < vec->size; i++) { + vec->vec[i] *= scalar; + } + + Py_INCREF( v1 ); + return v1; + + } + PyErr_SetString(PyExc_TypeError, "Vector multiplication: arguments not acceptable for this operation\n"); return NULL; } @@ -747,7 +746,7 @@ static PyObject *Vector_imul(PyObject * v1, PyObject * v2) divide*/ static PyObject *Vector_div(PyObject * v1, PyObject * v2) { - int i, size; + int i; float vec[4], scalar; VectorObject *vec1 = NULL; @@ -757,28 +756,28 @@ static PyObject *Vector_div(PyObject * v1, PyObject * v2) } vec1 = (VectorObject*)v1; /* vector */ - if(!PyNumber_Check(v2)) { /* parsed item not a number */ + scalar = (float)PyFloat_AsDouble(v2); + if(scalar== -1.0f && PyErr_Occurred()) { /* parsed item not a number */ PyErr_SetString(PyExc_TypeError, "Vector division: Vector must be divided by a float\n"); return NULL; } - scalar = (float)PyFloat_AsDouble(v2); if(scalar==0.0) { /* not a vector */ PyErr_SetString(PyExc_ZeroDivisionError, "Vector division: divide by zero error.\n"); return NULL; } - size = vec1->size; - for(i = 0; i < size; i++) { + + for(i = 0; i < vec1->size; i++) { vec[i] = vec1->vec[i] / scalar; } - return newVectorObject(vec, size, Py_NEW); + return newVectorObject(vec, vec1->size, Py_NEW); } -/*------------------------obj / obj------------------------------ +/*------------------------obj /= obj------------------------------ divide*/ static PyObject *Vector_idiv(PyObject * v1, PyObject * v2) { - int i, size; + int i; float scalar; VectorObject *vec1 = NULL; @@ -788,20 +787,18 @@ static PyObject *Vector_idiv(PyObject * v1, PyObject * v2) }*/ vec1 = (VectorObject*)v1; /* vector */ - - if(!PyNumber_Check(v2)) { /* parsed item not a number */ + + scalar = (float)PyFloat_AsDouble(v2); + if(scalar==-1.0f && PyErr_Occurred()) { /* parsed item not a number */ PyErr_SetString(PyExc_TypeError, "Vector division: Vector must be divided by a float\n"); return NULL; } - - scalar = (float)PyFloat_AsDouble(v2); if(scalar==0.0) { /* not a vector */ PyErr_SetString(PyExc_ZeroDivisionError, "Vector division: divide by zero error.\n"); return NULL; } - size = vec1->size; - for(i = 0; i < size; i++) { + for(i = 0; i < vec1->size; i++) { vec1->vec[i] /= scalar; } Py_INCREF( v1 ); @@ -820,24 +817,6 @@ static PyObject *Vector_neg(VectorObject *self) return newVectorObject(vec, self->size, Py_NEW); } -/*------------------------coerce(obj, obj)----------------------- - coercion of unknown types to type VectorObject for numeric protocols - Coercion() is called whenever a math operation has 2 operands that - it doesn't understand how to evaluate. 2+Matrix for example. We want to - evaluate some of these operations like: (vector * 2), however, for math - to proceed, the unknown operand must be cast to a type that python math will - understand. (e.g. in the case above case, 2 must be cast to a vector and - then call vector.multiply(vector, scalar_cast_as_vector)*/ - - -static int Vector_coerce(PyObject ** v1, PyObject ** v2) -{ - /* Just incref, each functon must raise errors for bad types */ - Py_INCREF (*v1); - Py_INCREF (*v2); - return 0; -} - /*------------------------tp_doc*/ static char VectorObject_doc[] = "This is a wrapper for vector objects."; @@ -949,15 +928,6 @@ static PySequenceMethods Vector_SeqMethods = { (ssizeobjargproc) Vector_ass_item, /* sq_ass_item */ (ssizessizeobjargproc) Vector_ass_slice, /* sq_ass_slice */ }; - - -/* For numbers without flag bit Py_TPFLAGS_CHECKTYPES set, all - arguments are guaranteed to be of the object's type (modulo - coercion hacks -- i.e. if the type's coercion function - returns other types, then these are allowed as well). Numbers that - have the Py_TPFLAGS_CHECKTYPES flag bit set should check *both* - arguments for proper type and implement the necessary conversions - in the slot functions themselves. */ static PyNumberMethods Vector_NumMethods = { (binaryfunc) Vector_add, /* __add__ */ @@ -977,11 +947,7 @@ static PyNumberMethods Vector_NumMethods = { (binaryfunc) NULL, /* __and__ */ (binaryfunc) NULL, /* __xor__ */ (binaryfunc) NULL, /* __or__ */ -#if 0 //XXX 2.5 - (coercion) Vector_coerce, /* __coerce__ */ -#else - 0, -#endif + /*(coercion)*/ NULL, /* __coerce__ */ (unaryfunc) NULL, /* __int__ */ (unaryfunc) NULL, /* __long__ */ (unaryfunc) NULL, /* __float__ */ @@ -1095,11 +1061,11 @@ static int Vector_setLength( VectorObject * self, PyObject * value ) double dot = 0.0f, param; int i; - if (!PyNumber_Check(value)) { - PyErr_SetString( PyExc_TypeError, "expected a number for the vector axis" ); + param= PyFloat_AsDouble( value ); + if(param==-1.0 && PyErr_Occurred()) { + PyErr_SetString(PyExc_TypeError, "length must be set to a number"); return -1; } - param= PyFloat_AsDouble( value ); if (param < 0) { PyErr_SetString( PyExc_TypeError, "cannot set a vectors length to a negative value" ); @@ -1229,12 +1195,13 @@ static int Vector_setSwizzle(VectorObject * self, PyObject * value, void *closur while (swizzleClosure & SWIZZLE_VALID_AXIS && axisB < listLen) { item = PyList_GetItem(value, axisB); - if (!PyNumber_Check(item)) - { + scalarVal = (float)PyFloat_AsDouble(item); + + if (scalarVal==-1.0 && PyErr_Occurred()) { PyErr_SetString(PyExc_AttributeError, "Error: vector does not have specified axis.\n"); return -1; } - scalarVal = (float)PyFloat_AsDouble(item); + axisA = swizzleClosure & SWIZZLE_AXIS; vecTemp[axisA] = scalarVal; @@ -1245,10 +1212,9 @@ static int Vector_setSwizzle(VectorObject * self, PyObject * value, void *closur memcpy(self->vec, vecTemp, axisB * sizeof(float)); return 0; } - else if (PyNumber_Check(value)) + else if (((scalarVal = (float)PyFloat_AsDouble(value)) == -1.0 && PyErr_Occurred())==0) { /* Assign the same value to each axis. */ - scalarVal = (float)PyFloat_AsDouble(value); swizzleClosure = (unsigned int) closure; while (swizzleClosure & SWIZZLE_VALID_AXIS) { @@ -1729,12 +1695,7 @@ PyTypeObject vector_Type = { NULL, /* PyBufferProcs *tp_as_buffer; */ /*** Flags to define presence of optional/expanded features ***/ -#if 0 //XXX 2.5 - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_CHECKTYPES, /* long tp_flags; */ -#else Py_TPFLAGS_DEFAULT, -#endif - VectorObject_doc, /* char *tp_doc; Documentation string */ /*** Assigned meaning in release 2.0 ***/ /* call function for all accessible objects */ |