diff options
author | Campbell Barton <ideasman42@gmail.com> | 2009-06-20 06:44:57 +0400 |
---|---|---|
committer | Campbell Barton <ideasman42@gmail.com> | 2009-06-20 06:44:57 +0400 |
commit | 7785ead4eb64f9702d7a59060e73b3e121e674a7 (patch) | |
tree | 0ea55feb030d8eff70bfe9758f3c4aafe1e7daf8 /source/blender/python/generic | |
parent | d0e8acaf2902235afd0b3fbd2e408c1cf04689be (diff) |
ObColor wasnt converted into an RNA string.
Updated Mathutils.Vector/Euler/Quaternion/Matrix so these are types rather then module methods, each type now has a tp_new function, matching python builtins float/int/str.
Also cleaned up float conversion and arg passing.
Changed buttons_objects.py...
if ob in groups.objects: # no longer works
if ob.name in groups.objects: # is the new syntax
...its more dict like and a lot faster (avoids python iterating over each item and comparing each, use a single rna lookup instead).
Diffstat (limited to 'source/blender/python/generic')
-rw-r--r-- | source/blender/python/generic/Mathutils.c | 388 | ||||
-rw-r--r-- | source/blender/python/generic/Mathutils.h | 21 | ||||
-rw-r--r-- | source/blender/python/generic/euler.c | 94 | ||||
-rw-r--r-- | source/blender/python/generic/euler.h | 7 | ||||
-rw-r--r-- | source/blender/python/generic/matrix.c | 121 | ||||
-rw-r--r-- | source/blender/python/generic/matrix.h | 12 | ||||
-rw-r--r-- | source/blender/python/generic/quat.c | 163 | ||||
-rw-r--r-- | source/blender/python/generic/quat.h | 10 | ||||
-rw-r--r-- | source/blender/python/generic/vector.c | 115 | ||||
-rw-r--r-- | source/blender/python/generic/vector.h | 11 |
10 files changed, 455 insertions, 487 deletions
diff --git a/source/blender/python/generic/Mathutils.c b/source/blender/python/generic/Mathutils.c index 637a42e2aa1..3c34a369baf 100644 --- a/source/blender/python/generic/Mathutils.c +++ b/source/blender/python/generic/Mathutils.c @@ -36,10 +36,6 @@ //-------------------------DOC STRINGS --------------------------- static char M_Mathutils_doc[] = "The Blender Mathutils module\n\n"; -static char M_Mathutils_Vector_doc[] = "() - create a new vector object from a list of floats"; -static char M_Mathutils_Matrix_doc[] = "() - create a new matrix object from a list of floats"; -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_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"; @@ -57,22 +53,36 @@ static char M_Mathutils_TriangleNormal_doc[] = "(v1, v2, v3) - returns the norma static char M_Mathutils_QuadNormal_doc[] = "(v1, v2, v3, v4) - returns the normal of the 3D quad defined"; static char M_Mathutils_LineIntersect_doc[] = "(v1, v2, v3, v4) - returns a tuple with the points on each line respectively closest to the other"; //-----------------------METHOD DEFINITIONS ---------------------- + +static PyObject *M_Mathutils_Rand(PyObject * self, PyObject * args); +static PyObject *M_Mathutils_AngleBetweenVecs(PyObject * self, PyObject * args); +static PyObject *M_Mathutils_MidpointVecs(PyObject * self, PyObject * args); +static PyObject *M_Mathutils_ProjectVecs(PyObject * self, PyObject * args); +static PyObject *M_Mathutils_RotationMatrix(PyObject * self, PyObject * args); +static PyObject *M_Mathutils_TranslationMatrix(PyObject * self, VectorObject * value); +static PyObject *M_Mathutils_ScaleMatrix(PyObject * self, PyObject * args); +static PyObject *M_Mathutils_OrthoProjectionMatrix(PyObject * self, PyObject * args); +static PyObject *M_Mathutils_ShearMatrix(PyObject * self, PyObject * args); +static PyObject *M_Mathutils_DifferenceQuats(PyObject * self, PyObject * args); +static PyObject *M_Mathutils_Slerp(PyObject * self, PyObject * args); +static PyObject *M_Mathutils_Intersect( PyObject * self, PyObject * args ); +static PyObject *M_Mathutils_TriangleArea( PyObject * self, PyObject * args ); +static PyObject *M_Mathutils_TriangleNormal( PyObject * self, PyObject * args ); +static PyObject *M_Mathutils_QuadNormal( PyObject * self, PyObject * args ); +static PyObject *M_Mathutils_LineIntersect( PyObject * self, PyObject * args ); + 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}, {"AngleBetweenVecs", (PyCFunction) M_Mathutils_AngleBetweenVecs, METH_VARARGS, M_Mathutils_AngleBetweenVecs_doc}, {"MidpointVecs", (PyCFunction) M_Mathutils_MidpointVecs, METH_VARARGS, M_Mathutils_MidpointVecs_doc}, {"ProjectVecs", (PyCFunction) M_Mathutils_ProjectVecs, METH_VARARGS, M_Mathutils_ProjectVecs_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}, {"OrthoProjectionMatrix", (PyCFunction) M_Mathutils_OrthoProjectionMatrix, METH_VARARGS, M_Mathutils_OrthoProjectionMatrix_doc}, - {"Quaternion", (PyCFunction) M_Mathutils_Quaternion, METH_VARARGS, M_Mathutils_Quaternion_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}, {"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}, @@ -80,6 +90,7 @@ struct PyMethodDef M_Mathutils_methods[] = { {"LineIntersect", ( PyCFunction ) M_Mathutils_LineIntersect, METH_VARARGS, M_Mathutils_LineIntersect_doc}, {NULL, NULL, 0, NULL} }; + /*----------------------------MODULE INIT-------------------------*/ /* from can be Blender.Mathutils or GameLogic.Mathutils for the BGE */ @@ -120,6 +131,12 @@ PyObject *Mathutils_Init(const char *from) submodule = Py_InitModule3(from, M_Mathutils_methods, M_Mathutils_doc); #endif + /* each type has its own new() function */ + PyModule_AddObject( submodule, "Vector", (PyObject *)&vector_Type ); + PyModule_AddObject( submodule, "Matrix", (PyObject *)&matrix_Type ); + PyModule_AddObject( submodule, "Euler", (PyObject *)&euler_Type ); + PyModule_AddObject( submodule, "Quaternion", (PyObject *)&quaternion_Type ); + return (submodule); } @@ -250,7 +267,7 @@ PyObject *quat_rotation(PyObject *arg1, PyObject *arg2) //----------------------------------Mathutils.Rand() -------------------- //returns a random number between a high and low value -PyObject *M_Mathutils_Rand(PyObject * self, PyObject * args) +static PyObject *M_Mathutils_Rand(PyObject * self, PyObject * args) { float high, low, range; double drand; @@ -278,65 +295,9 @@ PyObject *M_Mathutils_Rand(PyObject * self, PyObject * args) return PyFloat_FromDouble(drand); } //----------------------------------VECTOR FUNCTIONS--------------------- -//----------------------------------Mathutils.Vector() ------------------ -// Supports 2D, 3D, and 4D vector objects both int and float values -// accepted. Mixed float and int values accepted. Ints are parsed to float -PyObject *M_Mathutils_Vector(PyObject * self, PyObject * args) -{ - PyObject *listObject = NULL; - int size, i; - float vec[4], f; - PyObject *v; - - size = PySequence_Length(args); - if (size == 1) { - listObject = PySequence_GetItem(args, 0); - if (PySequence_Check(listObject)) { - size = PySequence_Length(listObject); - } else { // Single argument was not a sequence - Py_XDECREF(listObject); - PyErr_SetString(PyExc_TypeError, "Mathutils.Vector(): 2-4 floats or ints expected (optionally in a sequence)\n"); - return NULL; - } - } else if (size == 0) { - //returns a new empty 3d vector - return newVectorObject(NULL, 3, Py_NEW); - } else { - Py_INCREF(args); - listObject = args; - } - - if (size<2 || size>4) { // Invalid vector size - Py_XDECREF(listObject); - PyErr_SetString(PyExc_AttributeError, "Mathutils.Vector(): 2-4 floats or ints expected (optionally in a sequence)\n"); - return NULL; - } - - for (i=0; i<size; i++) { - v=PySequence_GetItem(listObject, i); - if (v==NULL) { // Failed to read sequence - Py_XDECREF(listObject); - PyErr_SetString(PyExc_RuntimeError, "Mathutils.Vector(): 2-4 floats or ints expected (optionally in a sequence)\n"); - return NULL; - } - - f= PyFloat_AsDouble(v); - if(f==-1 && PyErr_Occurred()) { // parsed item not a number - Py_DECREF(v); - Py_XDECREF(listObject); - PyErr_SetString(PyExc_TypeError, "Mathutils.Vector(): 2-4 floats or ints expected (optionally in a sequence)\n"); - return NULL; - } - - vec[i]= f; - Py_DECREF(v); - } - Py_DECREF(listObject); - return newVectorObject(vec, size, Py_NEW); -} //----------------------------------Mathutils.AngleBetweenVecs() --------- //calculates the angle between 2 vectors -PyObject *M_Mathutils_AngleBetweenVecs(PyObject * self, PyObject * args) +static PyObject *M_Mathutils_AngleBetweenVecs(PyObject * self, PyObject * args) { VectorObject *vec1 = NULL, *vec2 = NULL; double dot = 0.0f, angleRads, test_v1 = 0.0f, test_v2 = 0.0f; @@ -378,7 +339,7 @@ AttributeError2: } //----------------------------------Mathutils.MidpointVecs() ------------- //calculates the midpoint between 2 vectors -PyObject *M_Mathutils_MidpointVecs(PyObject * self, PyObject * args) +static PyObject *M_Mathutils_MidpointVecs(PyObject * self, PyObject * args) { VectorObject *vec1 = NULL, *vec2 = NULL; float vec[4]; @@ -400,7 +361,7 @@ PyObject *M_Mathutils_MidpointVecs(PyObject * self, PyObject * args) } //----------------------------------Mathutils.ProjectVecs() ------------- //projects vector 1 onto vector 2 -PyObject *M_Mathutils_ProjectVecs(PyObject * self, PyObject * args) +static PyObject *M_Mathutils_ProjectVecs(PyObject * self, PyObject * args) { VectorObject *vec1 = NULL, *vec2 = NULL; float vec[4]; @@ -432,94 +393,10 @@ PyObject *M_Mathutils_ProjectVecs(PyObject * self, PyObject * args) return newVectorObject(vec, size, Py_NEW); } //----------------------------------MATRIX FUNCTIONS-------------------- -//----------------------------------Mathutils.Matrix() ----------------- -//mat is a 1D array of floats - row[0][0],row[0][1], row[1][0], etc. -//create a new matrix type -PyObject *M_Mathutils_Matrix(PyObject * self, PyObject * args) -{ - PyObject *listObject = NULL; - PyObject *argObject, *m, *s, *f; - MatrixObject *mat; - int argSize, seqSize = 0, i, j; - float matrix[16] = {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, - 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f}; - - argSize = PySequence_Length(args); - if(argSize > 4){ //bad arg nums - PyErr_SetString(PyExc_AttributeError, "Mathutils.Matrix(): expects 0-4 numeric sequences of the same size\n"); - return NULL; - } else if (argSize == 0) { //return empty 4D matrix - return (PyObject *) newMatrixObject(NULL, 4, 4, Py_NEW); - }else if (argSize == 1){ - //copy constructor for matrix objects - argObject = PySequence_GetItem(args, 0); - if(MatrixObject_Check(argObject)){ - mat = (MatrixObject*)argObject; - - argSize = mat->rowSize; //rows - seqSize = mat->colSize; //col - for(i = 0; i < (seqSize * argSize); i++){ - matrix[i] = mat->contigPtr[i]; - } - } - Py_DECREF(argObject); - }else{ //2-4 arguments (all seqs? all same size?) - for(i =0; i < argSize; i++){ - argObject = PySequence_GetItem(args, i); - if (PySequence_Check(argObject)) { //seq? - if(seqSize){ //0 at first - if(PySequence_Length(argObject) != seqSize){ //seq size not same - Py_DECREF(argObject); - PyErr_SetString(PyExc_AttributeError, "Mathutils.Matrix(): expects 0-4 numeric sequences of the same size\n"); - return NULL; - } - } - seqSize = PySequence_Length(argObject); - }else{ //arg not a sequence - Py_XDECREF(argObject); - PyErr_SetString(PyExc_TypeError, "Mathutils.Matrix(): expects 0-4 numeric sequences of the same size\n"); - return NULL; - } - Py_DECREF(argObject); - } - //all is well... let's continue parsing - listObject = args; - for (i = 0; i < argSize; i++){ - m = PySequence_GetItem(listObject, i); - if (m == NULL) { // Failed to read sequence - PyErr_SetString(PyExc_RuntimeError, "Mathutils.Matrix(): failed to parse arguments...\n"); - return NULL; - } - - for (j = 0; j < seqSize; j++) { - s = PySequence_GetItem(m, j); - if (s == NULL) { // Failed to read sequence - Py_DECREF(m); - PyErr_SetString(PyExc_RuntimeError, "Mathutils.Matrix(): failed to parse arguments...\n"); - return NULL; - } - - f = PyNumber_Float(s); - if(f == NULL) { // parsed item is not a number - Py_DECREF(m); - Py_DECREF(s); - PyErr_SetString(PyExc_AttributeError, "Mathutils.Matrix(): expects 0-4 numeric sequences of the same size\n"); - return NULL; - } - - matrix[(seqSize*i)+j]=(float)PyFloat_AS_DOUBLE(f); - Py_DECREF(f); - Py_DECREF(s); - } - Py_DECREF(m); - } - } - return newMatrixObject(matrix, argSize, seqSize, Py_NEW); -} //----------------------------------Mathutils.RotationMatrix() ---------- //mat is a 1D array of floats - row[0][0],row[0][1], row[1][0], etc. //creates a rotation matrix -PyObject *M_Mathutils_RotationMatrix(PyObject * self, PyObject * args) +static PyObject *M_Mathutils_RotationMatrix(PyObject * self, PyObject * args) { VectorObject *vec = NULL; char *axis = NULL; @@ -648,7 +525,7 @@ PyObject *M_Mathutils_RotationMatrix(PyObject * self, PyObject * args) } //----------------------------------Mathutils.TranslationMatrix() ------- //creates a translation matrix -PyObject *M_Mathutils_TranslationMatrix(PyObject * self, VectorObject * vec) +static PyObject *M_Mathutils_TranslationMatrix(PyObject * self, VectorObject * vec) { float mat[16] = {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f}; @@ -672,7 +549,7 @@ PyObject *M_Mathutils_TranslationMatrix(PyObject * self, VectorObject * vec) //----------------------------------Mathutils.ScaleMatrix() ------------- //mat is a 1D array of floats - row[0][0],row[0][1], row[1][0], etc. //creates a scaling matrix -PyObject *M_Mathutils_ScaleMatrix(PyObject * self, PyObject * args) +static PyObject *M_Mathutils_ScaleMatrix(PyObject * self, PyObject * args) { VectorObject *vec = NULL; float norm = 0.0f, factor; @@ -746,7 +623,7 @@ PyObject *M_Mathutils_ScaleMatrix(PyObject * self, PyObject * args) //----------------------------------Mathutils.OrthoProjectionMatrix() --- //mat is a 1D array of floats - row[0][0],row[0][1], row[1][0], etc. //creates an ortho projection matrix -PyObject *M_Mathutils_OrthoProjectionMatrix(PyObject * self, PyObject * args) +static PyObject *M_Mathutils_OrthoProjectionMatrix(PyObject * self, PyObject * args) { VectorObject *vec = NULL; char *plane; @@ -844,7 +721,7 @@ PyObject *M_Mathutils_OrthoProjectionMatrix(PyObject * self, PyObject * args) } //----------------------------------Mathutils.ShearMatrix() ------------- //creates a shear matrix -PyObject *M_Mathutils_ShearMatrix(PyObject * self, PyObject * args) +static PyObject *M_Mathutils_ShearMatrix(PyObject * self, PyObject * args) { int matSize; char *plane; @@ -910,135 +787,10 @@ PyObject *M_Mathutils_ShearMatrix(PyObject * self, PyObject * args) return newMatrixObject(mat, matSize, matSize, Py_NEW); } //----------------------------------QUATERNION FUNCTIONS----------------- -//----------------------------------Mathutils.Quaternion() -------------- -PyObject *M_Mathutils_Quaternion(PyObject * self, PyObject * args) -{ - PyObject *listObject = NULL, *n, *q, *f; - int size, i; - float quat[4]; - double norm = 0.0f, angle = 0.0f; - - size = PySequence_Length(args); - if (size == 1 || size == 2) { //seq? - listObject = PySequence_GetItem(args, 0); - if (PySequence_Check(listObject)) { - size = PySequence_Length(listObject); - if ((size == 4 && PySequence_Length(args) !=1) || - (size == 3 && PySequence_Length(args) !=2) || (size >4 || size < 3)) { - // invalid args/size - Py_DECREF(listObject); - PyErr_SetString(PyExc_AttributeError, "Mathutils.Quaternion(): 4d numeric sequence expected or 3d vector and number\n"); - return NULL; - } - if(size == 3){ //get angle in axis/angle - n = PySequence_GetItem(args, 1); - if(n == NULL) { // parsed item not a number or getItem fail - Py_DECREF(listObject); - PyErr_SetString(PyExc_TypeError, "Mathutils.Quaternion(): 4d numeric sequence expected or 3d vector and number\n"); - return NULL; - } - - angle = PyFloat_AsDouble(n); - Py_DECREF(n); - - if (angle==-1 && PyErr_Occurred()) { - Py_DECREF(listObject); - PyErr_SetString(PyExc_TypeError, "Mathutils.Quaternion(): 4d numeric sequence expected or 3d vector and number\n"); - return NULL; - } - } - }else{ - Py_DECREF(listObject); /* assume the list is teh second arg */ - listObject = PySequence_GetItem(args, 1); - if (size>1 && PySequence_Check(listObject)) { - size = PySequence_Length(listObject); - if (size != 3) { - // invalid args/size - Py_DECREF(listObject); - PyErr_SetString(PyExc_AttributeError, "Mathutils.Quaternion(): 4d numeric sequence expected or 3d vector and number\n"); - return NULL; - } - n = PySequence_GetItem(args, 0); - if(n == NULL) { // parsed item not a number or getItem fail - Py_DECREF(listObject); - PyErr_SetString(PyExc_TypeError, "Mathutils.Quaternion(): 4d numeric sequence expected or 3d vector and number\n"); - return NULL; - } - angle = PyFloat_AsDouble(n); - Py_DECREF(n); - - if (angle==-1 && PyErr_Occurred()) { - Py_DECREF(listObject); - PyErr_SetString(PyExc_TypeError, "Mathutils.Quaternion(): 4d numeric sequence expected or 3d vector and number\n"); - return NULL; - } - } else { // argument was not a sequence - Py_XDECREF(listObject); - PyErr_SetString(PyExc_TypeError, "Mathutils.Quaternion(): 4d numeric sequence expected or 3d vector and number\n"); - return NULL; - } - } - } else if (size == 0) { //returns a new empty quat - return newQuaternionObject(NULL, Py_NEW); - } else { - Py_INCREF(args); - listObject = args; - } - - if (size == 3) { // invalid quat size - if(PySequence_Length(args) != 2){ - Py_DECREF(listObject); - PyErr_SetString(PyExc_AttributeError, "Mathutils.Quaternion(): 4d numeric sequence expected or 3d vector and number\n"); - return NULL; - } - }else{ - if(size != 4){ - Py_DECREF(listObject); - PyErr_SetString(PyExc_AttributeError, "Mathutils.Quaternion(): 4d numeric sequence expected or 3d vector and number\n"); - return NULL; - } - } - - for (i=0; i<size; i++) { //parse - q = PySequence_GetItem(listObject, i); - if (q == NULL) { // Failed to read sequence - Py_DECREF(listObject); - PyErr_SetString(PyExc_RuntimeError, "Mathutils.Quaternion(): 4d numeric sequence expected or 3d vector and number\n"); - return NULL; - } - - f = PyNumber_Float(q); - if(f == NULL) { // parsed item not a number - Py_DECREF(q); - Py_DECREF(listObject); - PyErr_SetString(PyExc_TypeError, "Mathutils.Quaternion(): 4d numeric sequence expected or 3d vector and number\n"); - return NULL; - } - - quat[i] = (float)PyFloat_AS_DOUBLE(f); - Py_DECREF(f); - Py_DECREF(q); - } - if(size == 3){ //calculate the quat based on axis/angle - norm = sqrt(quat[0] * quat[0] + quat[1] * quat[1] + quat[2] * quat[2]); - quat[0] /= (float)norm; - quat[1] /= (float)norm; - quat[2] /= (float)norm; - - angle = angle * (Py_PI / 180); - quat[3] =(float) (sin(angle/ 2.0f)) * quat[2]; - quat[2] =(float) (sin(angle/ 2.0f)) * quat[1]; - quat[1] =(float) (sin(angle/ 2.0f)) * quat[0]; - quat[0] =(float) (cos(angle/ 2.0f)); - } - - Py_DECREF(listObject); - return newQuaternionObject(quat, Py_NEW); -} //----------------------------------Mathutils.DifferenceQuats() --------- //returns the difference between 2 quaternions -PyObject *M_Mathutils_DifferenceQuats(PyObject * self, PyObject * args) +static PyObject *M_Mathutils_DifferenceQuats(PyObject * self, PyObject * args) { QuaternionObject *quatU = NULL, *quatV = NULL; float quat[4], tempQuat[4]; @@ -1065,7 +817,7 @@ PyObject *M_Mathutils_DifferenceQuats(PyObject * self, PyObject * args) } //----------------------------------Mathutils.Slerp() ------------------ //attemps to interpolate 2 quaternions and return the result -PyObject *M_Mathutils_Slerp(PyObject * self, PyObject * args) +static PyObject *M_Mathutils_Slerp(PyObject * self, PyObject * args) { QuaternionObject *quatU = NULL, *quatV = NULL; float quat[4], quat_u[4], quat_v[4], param; @@ -1121,67 +873,9 @@ PyObject *M_Mathutils_Slerp(PyObject * self, PyObject * args) return newQuaternionObject(quat, Py_NEW); } //----------------------------------EULER FUNCTIONS---------------------- -//----------------------------------Mathutils.Euler() ------------------- -//makes a new euler for you to play with -PyObject *M_Mathutils_Euler(PyObject * self, PyObject * args) -{ - - PyObject *listObject = NULL; - int size, i; - float eul[3]; - PyObject *e, *f; - - size = PySequence_Length(args); - if (size == 1) { - listObject = PySequence_GetItem(args, 0); - if (PySequence_Check(listObject)) { - size = PySequence_Length(listObject); - } else { // Single argument was not a sequence - Py_DECREF(listObject); - PyErr_SetString(PyExc_TypeError, "Mathutils.Euler(): 3d numeric sequence expected\n"); - return NULL; - } - } else if (size == 0) { - //returns a new empty 3d euler - return newEulerObject(NULL, Py_NEW); - } else { - Py_INCREF(args); - listObject = args; - } - - if (size != 3) { // Invalid euler size - Py_DECREF(listObject); - PyErr_SetString(PyExc_AttributeError, "Mathutils.Euler(): 3d numeric sequence expected\n"); - return NULL; - } - - for (i=0; i<size; i++) { - e = PySequence_GetItem(listObject, i); - if (e == NULL) { // Failed to read sequence - Py_DECREF(listObject); - PyErr_SetString(PyExc_RuntimeError, "Mathutils.Euler(): 3d numeric sequence expected\n"); - return NULL; - } - - f = PyNumber_Float(e); - if(f == NULL) { // parsed item not a number - Py_DECREF(e); - Py_DECREF(listObject); - PyErr_SetString(PyExc_TypeError, "Mathutils.Euler(): 3d numeric sequence expected\n"); - return NULL; - } - - eul[i]=(float)PyFloat_AS_DOUBLE(f); - Py_DECREF(f); - Py_DECREF(e); - } - Py_DECREF(listObject); - return newEulerObject(eul, Py_NEW); -} - //---------------------------------INTERSECTION FUNCTIONS-------------------- //----------------------------------Mathutils.Intersect() ------------------- -PyObject *M_Mathutils_Intersect( PyObject * self, PyObject * args ) +static PyObject *M_Mathutils_Intersect( PyObject * self, PyObject * args ) { VectorObject *ray, *ray_off, *vec1, *vec2, *vec3; float dir[3], orig[3], v1[3], v2[3], v3[3], e1[3], e2[3], pvec[3], tvec[3], qvec[3]; @@ -1251,7 +945,7 @@ PyObject *M_Mathutils_Intersect( PyObject * self, PyObject * args ) } //----------------------------------Mathutils.LineIntersect() ------------------- /* Line-Line intersection using algorithm from mathworld.wolfram.com */ -PyObject *M_Mathutils_LineIntersect( PyObject * self, PyObject * args ) +static PyObject *M_Mathutils_LineIntersect( PyObject * self, PyObject * args ) { PyObject * tuple; VectorObject *vec1, *vec2, *vec3, *vec4; @@ -1315,7 +1009,7 @@ PyObject *M_Mathutils_LineIntersect( PyObject * self, PyObject * args ) //---------------------------------NORMALS FUNCTIONS-------------------- //----------------------------------Mathutils.QuadNormal() ------------------- -PyObject *M_Mathutils_QuadNormal( PyObject * self, PyObject * args ) +static PyObject *M_Mathutils_QuadNormal( PyObject * self, PyObject * args ) { VectorObject *vec1; VectorObject *vec2; @@ -1362,7 +1056,7 @@ PyObject *M_Mathutils_QuadNormal( PyObject * self, PyObject * args ) } //----------------------------Mathutils.TriangleNormal() ------------------- -PyObject *M_Mathutils_TriangleNormal( PyObject * self, PyObject * args ) +static PyObject *M_Mathutils_TriangleNormal( PyObject * self, PyObject * args ) { VectorObject *vec1, *vec2, *vec3; float v1[3], v2[3], v3[3], e1[3], e2[3], n[3]; @@ -1396,7 +1090,7 @@ PyObject *M_Mathutils_TriangleNormal( PyObject * self, PyObject * args ) //--------------------------------- AREA FUNCTIONS-------------------- //----------------------------------Mathutils.TriangleArea() ------------------- -PyObject *M_Mathutils_TriangleArea( PyObject * self, PyObject * args ) +static PyObject *M_Mathutils_TriangleArea( PyObject * self, PyObject * args ) { VectorObject *vec1, *vec2, *vec3; float v1[3], v2[3], v3[3]; diff --git a/source/blender/python/generic/Mathutils.h b/source/blender/python/generic/Mathutils.h index af984c58db8..e8882c3dac2 100644 --- a/source/blender/python/generic/Mathutils.h +++ b/source/blender/python/generic/Mathutils.h @@ -44,27 +44,6 @@ PyObject *row_vector_multiplication(VectorObject* vec, MatrixObject * mat); PyObject *column_vector_multiplication(MatrixObject * mat, VectorObject* vec); PyObject *quat_rotation(PyObject *arg1, PyObject *arg2); -PyObject *M_Mathutils_Rand(PyObject * self, PyObject * args); -PyObject *M_Mathutils_Vector(PyObject * self, PyObject * args); -PyObject *M_Mathutils_AngleBetweenVecs(PyObject * self, PyObject * args); -PyObject *M_Mathutils_MidpointVecs(PyObject * self, PyObject * args); -PyObject *M_Mathutils_ProjectVecs(PyObject * self, PyObject * args); -PyObject *M_Mathutils_Matrix(PyObject * self, PyObject * args); -PyObject *M_Mathutils_RotationMatrix(PyObject * self, PyObject * args); -PyObject *M_Mathutils_TranslationMatrix(PyObject * self, VectorObject * value); -PyObject *M_Mathutils_ScaleMatrix(PyObject * self, PyObject * args); -PyObject *M_Mathutils_OrthoProjectionMatrix(PyObject * self, PyObject * args); -PyObject *M_Mathutils_ShearMatrix(PyObject * self, PyObject * args); -PyObject *M_Mathutils_Quaternion(PyObject * self, PyObject * args); -PyObject *M_Mathutils_DifferenceQuats(PyObject * self, PyObject * args); -PyObject *M_Mathutils_Slerp(PyObject * self, PyObject * args); -PyObject *M_Mathutils_Euler(PyObject * self, PyObject * args); -PyObject *M_Mathutils_Intersect( PyObject * self, PyObject * args ); -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 ); - 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/euler.c b/source/blender/python/generic/euler.c index 82131b10710..a65feb7e949 100644 --- a/source/blender/python/generic/euler.c +++ b/source/blender/python/generic/euler.c @@ -34,15 +34,24 @@ //-------------------------DOC STRINGS --------------------------- -char Euler_Zero_doc[] = "() - set all values in the euler to 0"; -char Euler_Unique_doc[] ="() - sets the euler rotation a unique shortest arc rotation - tests for gimbal lock"; -char Euler_ToMatrix_doc[] = "() - returns a rotation matrix representing the euler rotation"; -char Euler_ToQuat_doc[] = "() - returns a quaternion representing the euler rotation"; -char Euler_Rotate_doc[] = "() - rotate a euler by certain amount around an axis of rotation"; -char Euler_copy_doc[] = "() - returns a copy of the euler."; -char Euler_MakeCompatible_doc[] = "(euler) - Make this user compatible with another (no axis flipping)."; +static char Euler_Zero_doc[] = "() - set all values in the euler to 0"; +static char Euler_Unique_doc[] ="() - sets the euler rotation a unique shortest arc rotation - tests for gimbal lock"; +static char Euler_ToMatrix_doc[] = "() - returns a rotation matrix representing the euler rotation"; +static char Euler_ToQuat_doc[] = "() - returns a quaternion representing the euler rotation"; +static char Euler_Rotate_doc[] = "() - rotate a euler by certain amount around an axis of rotation"; +static char Euler_copy_doc[] = "() - returns a copy of the euler."; +static char Euler_MakeCompatible_doc[] = "(euler) - Make this user compatible with another (no axis flipping)."; + +static PyObject *Euler_Zero( EulerObject * self ); +static PyObject *Euler_Unique( EulerObject * self ); +static PyObject *Euler_ToMatrix( EulerObject * self ); +static PyObject *Euler_ToQuat( EulerObject * self ); +static PyObject *Euler_Rotate( EulerObject * self, PyObject *args ); +static PyObject *Euler_MakeCompatible( EulerObject * self, EulerObject *value ); +static PyObject *Euler_copy( EulerObject * self, PyObject *args ); + //-----------------------METHOD DEFINITIONS ---------------------- -struct PyMethodDef Euler_methods[] = { +static struct PyMethodDef Euler_methods[] = { {"zero", (PyCFunction) Euler_Zero, METH_NOARGS, Euler_Zero_doc}, {"unique", (PyCFunction) Euler_Unique, METH_NOARGS, Euler_Unique_doc}, {"toMatrix", (PyCFunction) Euler_ToMatrix, METH_NOARGS, Euler_ToMatrix_doc}, @@ -53,10 +62,63 @@ struct PyMethodDef Euler_methods[] = { {"copy", (PyCFunction) Euler_copy, METH_VARARGS, Euler_copy_doc}, {NULL, NULL, 0, NULL} }; + +//----------------------------------Mathutils.Euler() ------------------- +//makes a new euler for you to play with +static PyObject *Euler_new(PyObject * self, PyObject * args) +{ + + PyObject *listObject = NULL; + int size, i; + float eul[3], scalar; + PyObject *e; + + size = PyTuple_GET_SIZE(args); + if (size == 1) { + listObject = PyTuple_GET_ITEM(args, 0); + if (PySequence_Check(listObject)) { + size = PySequence_Length(listObject); + } else { // Single argument was not a sequence + PyErr_SetString(PyExc_TypeError, "Mathutils.Euler(): 3d numeric sequence expected\n"); + return NULL; + } + } else if (size == 0) { + //returns a new empty 3d euler + return newEulerObject(NULL, Py_NEW); + } else { + listObject = args; + } + + if (size != 3) { // Invalid euler size + PyErr_SetString(PyExc_AttributeError, "Mathutils.Euler(): 3d numeric sequence expected\n"); + return NULL; + } + + for (i=0; i<size; i++) { + e = PySequence_GetItem(listObject, i); + if (e == NULL) { // Failed to read sequence + Py_DECREF(listObject); + PyErr_SetString(PyExc_RuntimeError, "Mathutils.Euler(): 3d numeric sequence expected\n"); + return NULL; + } + + scalar= (float)PyFloat_AsDouble(e); + Py_DECREF(e); + + if(scalar==-1 && PyErr_Occurred()) { // parsed item is not a number + PyErr_SetString(PyExc_TypeError, "Mathutils.Euler(): 3d numeric sequence expected\n"); + return NULL; + } + + eul[i]= scalar; + } + return newEulerObject(eul, Py_NEW); +} + //-----------------------------METHODS---------------------------- //----------------------------Euler.toQuat()---------------------- //return a quaternion representation of the euler -PyObject *Euler_ToQuat(EulerObject * self) +static PyObject *Euler_ToQuat(EulerObject * self) { float eul[3], quat[4]; int x; @@ -69,7 +131,7 @@ PyObject *Euler_ToQuat(EulerObject * self) } //----------------------------Euler.toMatrix()--------------------- //return a matrix representation of the euler -PyObject *Euler_ToMatrix(EulerObject * self) +static PyObject *Euler_ToMatrix(EulerObject * self) { float eul[3]; float mat[9] = {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f}; @@ -83,7 +145,7 @@ PyObject *Euler_ToMatrix(EulerObject * self) } //----------------------------Euler.unique()----------------------- //sets the x,y,z values to a unique euler rotation -PyObject *Euler_Unique(EulerObject * self) +static PyObject *Euler_Unique(EulerObject * self) { double heading, pitch, bank; double pi2 = Py_PI * 2.0f; @@ -134,7 +196,7 @@ PyObject *Euler_Unique(EulerObject * self) } //----------------------------Euler.zero()------------------------- //sets the euler to 0,0,0 -PyObject *Euler_Zero(EulerObject * self) +static PyObject *Euler_Zero(EulerObject * self) { self->eul[0] = 0.0; self->eul[1] = 0.0; @@ -146,7 +208,7 @@ PyObject *Euler_Zero(EulerObject * self) //----------------------------Euler.rotate()----------------------- //rotates a euler a certain amount and returns the result //should return a unique euler rotation (i.e. no 720 degree pitches :) -PyObject *Euler_Rotate(EulerObject * self, PyObject *args) +static PyObject *Euler_Rotate(EulerObject * self, PyObject *args) { float angle = 0.0f; char *axis; @@ -176,7 +238,7 @@ PyObject *Euler_Rotate(EulerObject * self, PyObject *args) return (PyObject *)self; } -PyObject *Euler_MakeCompatible(EulerObject * self, EulerObject *value) +static PyObject *Euler_MakeCompatible(EulerObject * self, EulerObject *value) { float eul_from_rad[3]; int x; @@ -203,7 +265,7 @@ PyObject *Euler_MakeCompatible(EulerObject * self, EulerObject *value) //----------------------------Euler.rotate()----------------------- // return a copy of the euler -PyObject *Euler_copy(EulerObject * self, PyObject *args) +static PyObject *Euler_copy(EulerObject * self, PyObject *args) { return newEulerObject(self->eul, Py_NEW); } @@ -509,7 +571,7 @@ PyTypeObject euler_Type = { 0, //tp_dictoffset 0, //tp_init 0, //tp_alloc - 0, //tp_new + Euler_new, //tp_new 0, //tp_free 0, //tp_is_gc 0, //tp_bases diff --git a/source/blender/python/generic/euler.h b/source/blender/python/generic/euler.h index 773b024f174..3206668ffa0 100644 --- a/source/blender/python/generic/euler.h +++ b/source/blender/python/generic/euler.h @@ -54,13 +54,6 @@ be stored in py_data) or be a wrapper for data allocated through blender (stored in blend_data). This is an either/or struct not both*/ //prototypes -PyObject *Euler_Zero( EulerObject * self ); -PyObject *Euler_Unique( EulerObject * self ); -PyObject *Euler_ToMatrix( EulerObject * self ); -PyObject *Euler_ToQuat( EulerObject * self ); -PyObject *Euler_Rotate( EulerObject * self, PyObject *args ); -PyObject *Euler_MakeCompatible( EulerObject * self, EulerObject *value ); -PyObject *Euler_copy( EulerObject * self, PyObject *args ); PyObject *newEulerObject( float *eul, int type ); #endif /* EXPP_euler_h */ diff --git a/source/blender/python/generic/matrix.c b/source/blender/python/generic/matrix.c index 4b2c9d4a8a7..e2ab1c3c653 100644 --- a/source/blender/python/generic/matrix.c +++ b/source/blender/python/generic/matrix.c @@ -32,20 +32,34 @@ #include "BLI_blenlib.h" /*-------------------------DOC STRINGS ---------------------------*/ -char Matrix_Zero_doc[] = "() - set all values in the matrix to 0"; -char Matrix_Identity_doc[] = "() - set the square matrix to it's identity matrix"; -char Matrix_Transpose_doc[] = "() - set the matrix to it's transpose"; -char Matrix_Determinant_doc[] = "() - return the determinant of the matrix"; -char Matrix_Invert_doc[] = "() - set the matrix to it's inverse if an inverse is possible"; -char Matrix_TranslationPart_doc[] = "() - return a vector encompassing the translation of the matrix"; -char Matrix_RotationPart_doc[] = "() - return a vector encompassing the rotation of the matrix"; -char Matrix_scalePart_doc[] = "() - convert matrix to a 3D vector"; -char Matrix_Resize4x4_doc[] = "() - resize the matrix to a 4x4 square matrix"; -char Matrix_toEuler_doc[] = "(eul_compat) - convert matrix to a euler angle rotation, optional euler argument that the new euler will be made compatible with."; -char Matrix_toQuat_doc[] = "() - convert matrix to a quaternion rotation"; -char Matrix_copy_doc[] = "() - return a copy of the matrix"; +static char Matrix_Zero_doc[] = "() - set all values in the matrix to 0"; +static char Matrix_Identity_doc[] = "() - set the square matrix to it's identity matrix"; +static char Matrix_Transpose_doc[] = "() - set the matrix to it's transpose"; +static char Matrix_Determinant_doc[] = "() - return the determinant of the matrix"; +static char Matrix_Invert_doc[] = "() - set the matrix to it's inverse if an inverse is possible"; +static char Matrix_TranslationPart_doc[] = "() - return a vector encompassing the translation of the matrix"; +static char Matrix_RotationPart_doc[] = "() - return a vector encompassing the rotation of the matrix"; +static char Matrix_scalePart_doc[] = "() - convert matrix to a 3D vector"; +static char Matrix_Resize4x4_doc[] = "() - resize the matrix to a 4x4 square matrix"; +static char Matrix_toEuler_doc[] = "(eul_compat) - convert matrix to a euler angle rotation, optional euler argument that the new euler will be made compatible with."; +static char Matrix_toQuat_doc[] = "() - convert matrix to a quaternion rotation"; +static char Matrix_copy_doc[] = "() - return a copy of the matrix"; + +static PyObject *Matrix_Zero( MatrixObject * self ); +static PyObject *Matrix_Identity( MatrixObject * self ); +static PyObject *Matrix_Transpose( MatrixObject * self ); +static PyObject *Matrix_Determinant( MatrixObject * self ); +static PyObject *Matrix_Invert( MatrixObject * self ); +static PyObject *Matrix_TranslationPart( MatrixObject * self ); +static PyObject *Matrix_RotationPart( MatrixObject * self ); +static PyObject *Matrix_scalePart( MatrixObject * self ); +static PyObject *Matrix_Resize4x4( MatrixObject * self ); +static PyObject *Matrix_toEuler( MatrixObject * self, PyObject *args ); +static PyObject *Matrix_toQuat( MatrixObject * self ); +static PyObject *Matrix_copy( MatrixObject * self ); + /*-----------------------METHOD DEFINITIONS ----------------------*/ -struct PyMethodDef Matrix_methods[] = { +static struct PyMethodDef Matrix_methods[] = { {"zero", (PyCFunction) Matrix_Zero, METH_NOARGS, Matrix_Zero_doc}, {"identity", (PyCFunction) Matrix_Identity, METH_NOARGS, Matrix_Identity_doc}, {"transpose", (PyCFunction) Matrix_Transpose, METH_NOARGS, Matrix_Transpose_doc}, @@ -61,9 +75,86 @@ struct PyMethodDef Matrix_methods[] = { {"__copy__", (PyCFunction) Matrix_copy, METH_NOARGS, Matrix_copy_doc}, {NULL, NULL, 0, NULL} }; + +//----------------------------------Mathutils.Matrix() ----------------- +//mat is a 1D array of floats - row[0][0],row[0][1], row[1][0], etc. +//create a new matrix type +static PyObject *Matrix_new(PyTypeObject *type, PyObject *args, PyObject *kwds) +{ + PyObject *argObject, *m, *s; + MatrixObject *mat; + int argSize, seqSize = 0, i, j; + float matrix[16] = {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f}; + float scalar; + + argSize = PyTuple_GET_SIZE(args); + if(argSize > 4){ //bad arg nums + PyErr_SetString(PyExc_AttributeError, "Mathutils.Matrix(): expects 0-4 numeric sequences of the same size\n"); + return NULL; + } else if (argSize == 0) { //return empty 4D matrix + return (PyObject *) newMatrixObject(NULL, 4, 4, Py_NEW); + }else if (argSize == 1){ + //copy constructor for matrix objects + argObject = PyTuple_GET_ITEM(args, 0); + if(MatrixObject_Check(argObject)){ + mat = (MatrixObject*)argObject; + + argSize = mat->rowSize; //rows + seqSize = mat->colSize; //col + for(i = 0; i < (seqSize * argSize); i++){ + matrix[i] = mat->contigPtr[i]; + } + } + }else{ //2-4 arguments (all seqs? all same size?) + for(i =0; i < argSize; i++){ + argObject = PyTuple_GET_ITEM(args, i); + if (PySequence_Check(argObject)) { //seq? + if(seqSize){ //0 at first + if(PySequence_Length(argObject) != seqSize){ //seq size not same + PyErr_SetString(PyExc_AttributeError, "Mathutils.Matrix(): expects 0-4 numeric sequences of the same size\n"); + return NULL; + } + } + seqSize = PySequence_Length(argObject); + }else{ //arg not a sequence + PyErr_SetString(PyExc_TypeError, "Mathutils.Matrix(): expects 0-4 numeric sequences of the same size\n"); + return NULL; + } + } + //all is well... let's continue parsing + for (i = 0; i < argSize; i++){ + m = PyTuple_GET_ITEM(args, i); + if (m == NULL) { // Failed to read sequence + PyErr_SetString(PyExc_RuntimeError, "Mathutils.Matrix(): failed to parse arguments...\n"); + return NULL; + } + + for (j = 0; j < seqSize; j++) { + s = PySequence_GetItem(m, j); + if (s == NULL) { // Failed to read sequence + PyErr_SetString(PyExc_RuntimeError, "Mathutils.Matrix(): failed to parse arguments...\n"); + return NULL; + } + + scalar= (float)PyFloat_AsDouble(s); + Py_DECREF(s); + + if(scalar==-1 && PyErr_Occurred()) { // parsed item is not a number + PyErr_SetString(PyExc_AttributeError, "Mathutils.Matrix(): expects 0-4 numeric sequences of the same size\n"); + return NULL; + } + + matrix[(seqSize*i)+j]= scalar; + } + } + } + return newMatrixObject(matrix, argSize, seqSize, Py_NEW); +} + /*-----------------------------METHODS----------------------------*/ /*---------------------------Matrix.toQuat() ---------------------*/ -PyObject *Matrix_toQuat(MatrixObject * self) +static PyObject *Matrix_toQuat(MatrixObject * self) { float quat[4]; @@ -872,7 +963,7 @@ PyTypeObject matrix_Type = { 0, /*tp_dictoffset*/ 0, /*tp_init*/ 0, /*tp_alloc*/ - 0, /*tp_new*/ + Matrix_new, /*tp_new*/ 0, /*tp_free*/ 0, /*tp_is_gc*/ 0, /*tp_bases*/ diff --git a/source/blender/python/generic/matrix.h b/source/blender/python/generic/matrix.h index 4658f4b5f6c..ef82263fe00 100644 --- a/source/blender/python/generic/matrix.h +++ b/source/blender/python/generic/matrix.h @@ -56,18 +56,6 @@ be stored in py_data) or be a wrapper for data allocated through blender (stored in blend_data). This is an either/or struct not both*/ /*prototypes*/ -PyObject *Matrix_Zero( MatrixObject * self ); -PyObject *Matrix_Identity( MatrixObject * self ); -PyObject *Matrix_Transpose( MatrixObject * self ); -PyObject *Matrix_Determinant( MatrixObject * self ); -PyObject *Matrix_Invert( MatrixObject * self ); -PyObject *Matrix_TranslationPart( MatrixObject * self ); -PyObject *Matrix_RotationPart( MatrixObject * self ); -PyObject *Matrix_scalePart( MatrixObject * self ); -PyObject *Matrix_Resize4x4( MatrixObject * self ); -PyObject *Matrix_toEuler( MatrixObject * self, PyObject *args ); -PyObject *Matrix_toQuat( MatrixObject * self ); -PyObject *Matrix_copy( MatrixObject * self ); PyObject *newMatrixObject(float *mat, int rowSize, int colSize, int type); #endif /* EXPP_matrix_H */ diff --git a/source/blender/python/generic/quat.c b/source/blender/python/generic/quat.c index c3c9e28c520..4ad5d07b3b8 100644 --- a/source/blender/python/generic/quat.c +++ b/source/blender/python/generic/quat.c @@ -34,18 +34,30 @@ //-------------------------DOC STRINGS --------------------------- -char Quaternion_Identity_doc[] = "() - set the quaternion to it's identity (1, vector)"; -char Quaternion_Negate_doc[] = "() - set all values in the quaternion to their negative"; -char Quaternion_Conjugate_doc[] = "() - set the quaternion to it's conjugate"; -char Quaternion_Inverse_doc[] = "() - set the quaternion to it's inverse"; -char Quaternion_Normalize_doc[] = "() - normalize the vector portion of the quaternion"; -char Quaternion_ToEuler_doc[] = "(eul_compat) - return a euler rotation representing the quaternion, optional euler argument that the new euler will be made compatible with."; -char Quaternion_ToMatrix_doc[] = "() - return a rotation matrix representing the quaternion"; -char Quaternion_Cross_doc[] = "(other) - return the cross product between this quaternion and another"; -char Quaternion_Dot_doc[] = "(other) - return the dot product between this quaternion and another"; -char Quaternion_copy_doc[] = "() - return a copy of the quat"; +static char Quaternion_Identity_doc[] = "() - set the quaternion to it's identity (1, vector)"; +static char Quaternion_Negate_doc[] = "() - set all values in the quaternion to their negative"; +static char Quaternion_Conjugate_doc[] = "() - set the quaternion to it's conjugate"; +static char Quaternion_Inverse_doc[] = "() - set the quaternion to it's inverse"; +static char Quaternion_Normalize_doc[] = "() - normalize the vector portion of the quaternion"; +static char Quaternion_ToEuler_doc[] = "(eul_compat) - return a euler rotation representing the quaternion, optional euler argument that the new euler will be made compatible with."; +static char Quaternion_ToMatrix_doc[] = "() - return a rotation matrix representing the quaternion"; +static char Quaternion_Cross_doc[] = "(other) - return the cross product between this quaternion and another"; +static char Quaternion_Dot_doc[] = "(other) - return the dot product between this quaternion and another"; +static char Quaternion_copy_doc[] = "() - return a copy of the quat"; + +static PyObject *Quaternion_Identity( QuaternionObject * self ); +static PyObject *Quaternion_Negate( QuaternionObject * self ); +static PyObject *Quaternion_Conjugate( QuaternionObject * self ); +static PyObject *Quaternion_Inverse( QuaternionObject * self ); +static PyObject *Quaternion_Normalize( QuaternionObject * self ); +static PyObject *Quaternion_ToEuler( QuaternionObject * self, PyObject *args ); +static PyObject *Quaternion_ToMatrix( QuaternionObject * self ); +static PyObject *Quaternion_Cross( QuaternionObject * self, QuaternionObject * value ); +static PyObject *Quaternion_Dot( QuaternionObject * self, QuaternionObject * value ); +static PyObject *Quaternion_copy( QuaternionObject * self ); + //-----------------------METHOD DEFINITIONS ---------------------- -struct PyMethodDef Quaternion_methods[] = { +static struct PyMethodDef Quaternion_methods[] = { {"identity", (PyCFunction) Quaternion_Identity, METH_NOARGS, Quaternion_Identity_doc}, {"negate", (PyCFunction) Quaternion_Negate, METH_NOARGS, Quaternion_Negate_doc}, {"conjugate", (PyCFunction) Quaternion_Conjugate, METH_NOARGS, Quaternion_Conjugate_doc}, @@ -59,10 +71,117 @@ struct PyMethodDef Quaternion_methods[] = { {"copy", (PyCFunction) Quaternion_copy, METH_NOARGS, Quaternion_copy_doc}, {NULL, NULL, 0, NULL} }; + +//----------------------------------Mathutils.Quaternion() -------------- +static PyObject *Quaternion_new(PyTypeObject *type, PyObject *args, PyObject *kwds) +{ + PyObject *listObject = NULL, *n, *q, *f; + int size, i; + float quat[4], scalar; + double norm = 0.0f, angle = 0.0f; + + size = PyTuple_GET_SIZE(args); + if (size == 1 || size == 2) { //seq? + listObject = PyTuple_GET_ITEM(args, 0); + if (PySequence_Check(listObject)) { + size = PySequence_Length(listObject); + if ((size == 4 && PySequence_Length(args) !=1) || + (size == 3 && PySequence_Length(args) !=2) || (size >4 || size < 3)) { + // invalid args/size + PyErr_SetString(PyExc_AttributeError, "Mathutils.Quaternion(): 4d numeric sequence expected or 3d vector and number\n"); + return NULL; + } + if(size == 3){ //get angle in axis/angle + n = PySequence_GetItem(args, 1); + if(n == NULL) { // parsed item not a number or getItem fail + PyErr_SetString(PyExc_TypeError, "Mathutils.Quaternion(): 4d numeric sequence expected or 3d vector and number\n"); + return NULL; + } + + angle = PyFloat_AsDouble(n); + Py_DECREF(n); + + if (angle==-1 && PyErr_Occurred()) { + PyErr_SetString(PyExc_TypeError, "Mathutils.Quaternion(): 4d numeric sequence expected or 3d vector and number\n"); + return NULL; + } + } + }else{ + listObject = PyTuple_GET_ITEM(args, 1); + if (size>1 && PySequence_Check(listObject)) { + size = PySequence_Length(listObject); + if (size != 3) { + // invalid args/size + PyErr_SetString(PyExc_AttributeError, "Mathutils.Quaternion(): 4d numeric sequence expected or 3d vector and number\n"); + return NULL; + } + angle = PyFloat_AsDouble(PyTuple_GET_ITEM(args, 0)); + + if (angle==-1 && PyErr_Occurred()) { + PyErr_SetString(PyExc_TypeError, "Mathutils.Quaternion(): 4d numeric sequence expected or 3d vector and number\n"); + return NULL; + } + } else { // argument was not a sequence + PyErr_SetString(PyExc_TypeError, "Mathutils.Quaternion(): 4d numeric sequence expected or 3d vector and number\n"); + return NULL; + } + } + } else if (size == 0) { //returns a new empty quat + return newQuaternionObject(NULL, Py_NEW); + } else { + listObject = args; + } + + if (size == 3) { // invalid quat size + if(PySequence_Length(args) != 2){ + PyErr_SetString(PyExc_AttributeError, "Mathutils.Quaternion(): 4d numeric sequence expected or 3d vector and number\n"); + return NULL; + } + }else{ + if(size != 4){ + PyErr_SetString(PyExc_AttributeError, "Mathutils.Quaternion(): 4d numeric sequence expected or 3d vector and number\n"); + return NULL; + } + } + + for (i=0; i<size; i++) { //parse + q = PySequence_GetItem(listObject, i); + if (q == NULL) { // Failed to read sequence + PyErr_SetString(PyExc_RuntimeError, "Mathutils.Quaternion(): 4d numeric sequence expected or 3d vector and number\n"); + return NULL; + } + + scalar = PyFloat_AsDouble(q); + if (scalar==-1 && PyErr_Occurred()) { + Py_DECREF(q); + PyErr_SetString(PyExc_TypeError, "Mathutils.Quaternion(): 4d numeric sequence expected or 3d vector and number\n"); + return NULL; + } + + quat[i] = scalar; + Py_DECREF(f); + Py_DECREF(q); + } + if(size == 3){ //calculate the quat based on axis/angle + norm = sqrt(quat[0] * quat[0] + quat[1] * quat[1] + quat[2] * quat[2]); + quat[0] /= (float)norm; + quat[1] /= (float)norm; + quat[2] /= (float)norm; + + angle = angle * (Py_PI / 180); + quat[3] =(float) (sin(angle/ 2.0f)) * quat[2]; + quat[2] =(float) (sin(angle/ 2.0f)) * quat[1]; + quat[1] =(float) (sin(angle/ 2.0f)) * quat[0]; + quat[0] =(float) (cos(angle/ 2.0f)); + } + + return newQuaternionObject(quat, Py_NEW); +} + //-----------------------------METHODS------------------------------ //----------------------------Quaternion.toEuler()------------------ //return the quat as a euler -PyObject *Quaternion_ToEuler(QuaternionObject * self, PyObject *args) +static PyObject *Quaternion_ToEuler(QuaternionObject * self, PyObject *args) { float eul[3]; EulerObject *eul_compat = NULL; @@ -93,7 +212,7 @@ PyObject *Quaternion_ToEuler(QuaternionObject * self, PyObject *args) } //----------------------------Quaternion.toMatrix()------------------ //return the quat as a matrix -PyObject *Quaternion_ToMatrix(QuaternionObject * self) +static PyObject *Quaternion_ToMatrix(QuaternionObject * self) { float mat[9] = {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f}; QuatToMat3(self->quat, (float (*)[3]) mat); @@ -103,7 +222,7 @@ PyObject *Quaternion_ToMatrix(QuaternionObject * self) //----------------------------Quaternion.cross(other)------------------ //return the cross quat -PyObject *Quaternion_Cross(QuaternionObject * self, QuaternionObject * value) +static PyObject *Quaternion_Cross(QuaternionObject * self, QuaternionObject * value) { float quat[4]; @@ -118,7 +237,7 @@ PyObject *Quaternion_Cross(QuaternionObject * self, QuaternionObject * value) //----------------------------Quaternion.dot(other)------------------ //return the dot quat -PyObject *Quaternion_Dot(QuaternionObject * self, QuaternionObject * value) +static PyObject *Quaternion_Dot(QuaternionObject * self, QuaternionObject * value) { int x; double dot = 0.0; @@ -136,7 +255,7 @@ PyObject *Quaternion_Dot(QuaternionObject * self, QuaternionObject * value) //----------------------------Quaternion.normalize()---------------- //normalize the axis of rotation of [theta,vector] -PyObject *Quaternion_Normalize(QuaternionObject * self) +static PyObject *Quaternion_Normalize(QuaternionObject * self) { NormalQuat(self->quat); Py_INCREF(self); @@ -144,7 +263,7 @@ PyObject *Quaternion_Normalize(QuaternionObject * self) } //----------------------------Quaternion.inverse()------------------ //invert the quat -PyObject *Quaternion_Inverse(QuaternionObject * self) +static PyObject *Quaternion_Inverse(QuaternionObject * self) { double mag = 0.0f; int x; @@ -165,7 +284,7 @@ PyObject *Quaternion_Inverse(QuaternionObject * self) } //----------------------------Quaternion.identity()----------------- //generate the identity quaternion -PyObject *Quaternion_Identity(QuaternionObject * self) +static PyObject *Quaternion_Identity(QuaternionObject * self) { self->quat[0] = 1.0; self->quat[1] = 0.0; @@ -177,7 +296,7 @@ PyObject *Quaternion_Identity(QuaternionObject * self) } //----------------------------Quaternion.negate()------------------- //negate the quat -PyObject *Quaternion_Negate(QuaternionObject * self) +static PyObject *Quaternion_Negate(QuaternionObject * self) { int x; for(x = 0; x < 4; x++) { @@ -188,7 +307,7 @@ PyObject *Quaternion_Negate(QuaternionObject * self) } //----------------------------Quaternion.conjugate()---------------- //negate the vector part -PyObject *Quaternion_Conjugate(QuaternionObject * self) +static PyObject *Quaternion_Conjugate(QuaternionObject * self) { int x; for(x = 1; x < 4; x++) { @@ -199,7 +318,7 @@ PyObject *Quaternion_Conjugate(QuaternionObject * self) } //----------------------------Quaternion.copy()---------------- //return a copy of the quat -PyObject *Quaternion_copy(QuaternionObject * self) +static PyObject *Quaternion_copy(QuaternionObject * self) { return newQuaternionObject(self->quat, Py_NEW); } @@ -680,7 +799,7 @@ PyTypeObject quaternion_Type = { 0, //tp_dictoffset 0, //tp_init 0, //tp_alloc - 0, //tp_new + Quaternion_new, //tp_new 0, //tp_free 0, //tp_is_gc 0, //tp_bases diff --git a/source/blender/python/generic/quat.h b/source/blender/python/generic/quat.h index 8887b147705..cfb50e4dbe1 100644 --- a/source/blender/python/generic/quat.h +++ b/source/blender/python/generic/quat.h @@ -54,16 +54,6 @@ be stored in py_data) or be a wrapper for data allocated through blender (stored in blend_data). This is an either/or struct not both*/ //prototypes -PyObject *Quaternion_Identity( QuaternionObject * self ); -PyObject *Quaternion_Negate( QuaternionObject * self ); -PyObject *Quaternion_Conjugate( QuaternionObject * self ); -PyObject *Quaternion_Inverse( QuaternionObject * self ); -PyObject *Quaternion_Normalize( QuaternionObject * self ); -PyObject *Quaternion_ToEuler( QuaternionObject * self, PyObject *args ); -PyObject *Quaternion_ToMatrix( QuaternionObject * self ); -PyObject *Quaternion_Cross( QuaternionObject * self, QuaternionObject * value ); -PyObject *Quaternion_Dot( QuaternionObject * self, QuaternionObject * value ); -PyObject *Quaternion_copy( QuaternionObject * self ); PyObject *newQuaternionObject( float *quat, int type ); #endif /* EXPP_quat_h */ diff --git a/source/blender/python/generic/vector.c b/source/blender/python/generic/vector.c index e2009d9974e..562413c6967 100644 --- a/source/blender/python/generic/vector.c +++ b/source/blender/python/generic/vector.c @@ -40,20 +40,32 @@ #define SWIZZLE_AXIS 0x3 /*-------------------------DOC STRINGS ---------------------------*/ -char Vector_Zero_doc[] = "() - set all values in the vector to 0"; -char Vector_Normalize_doc[] = "() - normalize the vector"; -char Vector_Negate_doc[] = "() - changes vector to it's additive inverse"; -char Vector_Resize2D_doc[] = "() - resize a vector to [x,y]"; -char Vector_Resize3D_doc[] = "() - resize a vector to [x,y,z]"; -char Vector_Resize4D_doc[] = "() - resize a vector to [x,y,z,w]"; -char Vector_ToTrackQuat_doc[] = "(track, up) - extract a quaternion from the vector and the track and up axis"; -char Vector_Reflect_doc[] = "(mirror) - return a vector reflected on the mirror normal"; -char Vector_Cross_doc[] = "(other) - return the cross product between this vector and another"; -char Vector_Dot_doc[] = "(other) - return the dot product between this vector and another"; -char Vector_copy_doc[] = "() - return a copy of the vector"; -char Vector_swizzle_doc[] = "Swizzle: Get or set axes in specified order"; +static char Vector_Zero_doc[] = "() - set all values in the vector to 0"; +static char Vector_Normalize_doc[] = "() - normalize the vector"; +static char Vector_Negate_doc[] = "() - changes vector to it's additive inverse"; +static char Vector_Resize2D_doc[] = "() - resize a vector to [x,y]"; +static char Vector_Resize3D_doc[] = "() - resize a vector to [x,y,z]"; +static char Vector_Resize4D_doc[] = "() - resize a vector to [x,y,z,w]"; +static char Vector_ToTrackQuat_doc[] = "(track, up) - extract a quaternion from the vector and the track and up axis"; +static char Vector_Reflect_doc[] = "(mirror) - return a vector reflected on the mirror normal"; +static char Vector_Cross_doc[] = "(other) - return the cross product between this vector and another"; +static char Vector_Dot_doc[] = "(other) - return the dot product between this vector and another"; +static char Vector_copy_doc[] = "() - return a copy of the vector"; +static char Vector_swizzle_doc[] = "Swizzle: Get or set axes in specified order"; /*-----------------------METHOD DEFINITIONS ----------------------*/ -struct PyMethodDef Vector_methods[] = { +static PyObject *Vector_Zero( VectorObject * self ); +static PyObject *Vector_Normalize( VectorObject * self ); +static PyObject *Vector_Negate( VectorObject * self ); +static PyObject *Vector_Resize2D( VectorObject * self ); +static PyObject *Vector_Resize3D( VectorObject * self ); +static PyObject *Vector_Resize4D( VectorObject * self ); +static PyObject *Vector_ToTrackQuat( VectorObject * self, PyObject * args ); +static PyObject *Vector_Reflect( VectorObject * self, PyObject * value ); +static PyObject *Vector_Cross( VectorObject * self, VectorObject * value ); +static PyObject *Vector_Dot( VectorObject * self, VectorObject * value ); +static PyObject *Vector_copy( VectorObject * self ); + +static struct PyMethodDef Vector_methods[] = { {"zero", (PyCFunction) Vector_Zero, METH_NOARGS, Vector_Zero_doc}, {"normalize", (PyCFunction) Vector_Normalize, METH_NOARGS, Vector_Normalize_doc}, {"negate", (PyCFunction) Vector_Negate, METH_NOARGS, Vector_Negate_doc}, @@ -69,10 +81,61 @@ struct PyMethodDef Vector_methods[] = { {NULL, NULL, 0, NULL} }; +//----------------------------------Mathutils.Vector() ------------------ +// Supports 2D, 3D, and 4D vector objects both int and float values +// accepted. Mixed float and int values accepted. Ints are parsed to float +static PyObject *Vector_new(PyTypeObject *type, PyObject *args, PyObject *kwds) +{ + PyObject *listObject = NULL; + int size, i; + float vec[4], f; + PyObject *v; + + size = PyTuple_GET_SIZE(args); /* we know its a tuple because its an arg */ + if (size == 1) { + listObject = PyTuple_GET_ITEM(args, 0); + if (PySequence_Check(listObject)) { + size = PySequence_Length(listObject); + } else { // Single argument was not a sequence + PyErr_SetString(PyExc_TypeError, "Mathutils.Vector(): 2-4 floats or ints expected (optionally in a sequence)\n"); + return NULL; + } + } else if (size == 0) { + //returns a new empty 3d vector + return newVectorObject(NULL, 3, Py_NEW); + } else { + listObject = args; + } + + if (size<2 || size>4) { // Invalid vector size + PyErr_SetString(PyExc_AttributeError, "Mathutils.Vector(): 2-4 floats or ints expected (optionally in a sequence)\n"); + return NULL; + } + + for (i=0; i<size; i++) { + v=PySequence_GetItem(listObject, i); + if (v==NULL) { // Failed to read sequence + PyErr_SetString(PyExc_RuntimeError, "Mathutils.Vector(): 2-4 floats or ints expected (optionally in a sequence)\n"); + return NULL; + } + + f= PyFloat_AsDouble(v); + if(f==-1 && PyErr_Occurred()) { // parsed item not a number + Py_DECREF(v); + PyErr_SetString(PyExc_TypeError, "Mathutils.Vector(): 2-4 floats or ints expected (optionally in a sequence)\n"); + return NULL; + } + + vec[i]= f; + Py_DECREF(v); + } + return newVectorObject(vec, size, Py_NEW); +} + /*-----------------------------METHODS---------------------------- */ /*----------------------------Vector.zero() ---------------------- set the vector data to 0,0,0 */ -PyObject *Vector_Zero(VectorObject * self) +static PyObject *Vector_Zero(VectorObject * self) { int i; for(i = 0; i < self->size; i++) { @@ -83,7 +146,7 @@ PyObject *Vector_Zero(VectorObject * self) } /*----------------------------Vector.normalize() ----------------- normalize the vector data to a unit vector */ -PyObject *Vector_Normalize(VectorObject * self) +static PyObject *Vector_Normalize(VectorObject * self) { int i; float norm = 0.0f; @@ -102,7 +165,7 @@ PyObject *Vector_Normalize(VectorObject * self) /*----------------------------Vector.resize2D() ------------------ resize the vector to x,y */ -PyObject *Vector_Resize2D(VectorObject * self) +static PyObject *Vector_Resize2D(VectorObject * self) { if(self->wrapped==Py_WRAP) { PyErr_SetString(PyExc_TypeError, "vector.resize2d(): cannot resize wrapped data - only python vectors\n"); @@ -120,7 +183,7 @@ PyObject *Vector_Resize2D(VectorObject * self) } /*----------------------------Vector.resize3D() ------------------ resize the vector to x,y,z */ -PyObject *Vector_Resize3D(VectorObject * self) +static PyObject *Vector_Resize3D(VectorObject * self) { if (self->wrapped==Py_WRAP) { PyErr_SetString(PyExc_TypeError, "vector.resize3d(): cannot resize wrapped data - only python vectors\n"); @@ -141,7 +204,7 @@ PyObject *Vector_Resize3D(VectorObject * self) } /*----------------------------Vector.resize4D() ------------------ resize the vector to x,y,z,w */ -PyObject *Vector_Resize4D(VectorObject * self) +static PyObject *Vector_Resize4D(VectorObject * self) { if(self->wrapped==Py_WRAP) { PyErr_SetString(PyExc_TypeError, "vector.resize4d(): cannot resize wrapped data - only python vectors"); @@ -164,7 +227,7 @@ PyObject *Vector_Resize4D(VectorObject * self) } /*----------------------------Vector.toTrackQuat(track, up) ---------------------- extract a quaternion from the vector and the track and up axis */ -PyObject *Vector_ToTrackQuat( VectorObject * self, PyObject * args ) +static PyObject *Vector_ToTrackQuat( VectorObject * self, PyObject * args ) { float vec[3], quat[4]; char *strack, *sup; @@ -279,7 +342,7 @@ PyObject *Vector_ToTrackQuat( VectorObject * self, PyObject * args ) return a reflected vector on the mirror normal ((2 * DotVecs(vec, mirror)) * mirror) - vec using arithb.c would be nice here */ -PyObject *Vector_Reflect( VectorObject * self, PyObject * value ) +static PyObject *Vector_Reflect( VectorObject * self, PyObject * value ) { VectorObject *mirrvec; float mirror[3]; @@ -326,7 +389,7 @@ PyObject *Vector_Reflect( VectorObject * self, PyObject * value ) return newVectorObject(reflect, self->size, Py_NEW); } -PyObject *Vector_Cross( VectorObject * self, VectorObject * value ) +static PyObject *Vector_Cross( VectorObject * self, VectorObject * value ) { VectorObject *vecCross = NULL; @@ -345,7 +408,7 @@ PyObject *Vector_Cross( VectorObject * self, VectorObject * value ) return (PyObject *)vecCross; } -PyObject *Vector_Dot( VectorObject * self, VectorObject * value ) +static PyObject *Vector_Dot( VectorObject * self, VectorObject * value ) { double dot = 0.0; int x; @@ -368,7 +431,7 @@ PyObject *Vector_Dot( VectorObject * self, VectorObject * value ) /*----------------------------Vector.copy() -------------------------------------- return a copy of the vector */ -PyObject *Vector_copy(VectorObject * self) +static PyObject *Vector_copy(VectorObject * self) { return newVectorObject(self->vec, self->size, Py_NEW); } @@ -839,7 +902,7 @@ static double vec_magnitude_nosqrt(float *data, int size) /*------------------------tp_richcmpr returns -1 execption, 0 false, 1 true */ -PyObject* Vector_richcmpr(PyObject *objectA, PyObject *objectB, int comparison_type) +static PyObject* Vector_richcmpr(PyObject *objectA, PyObject *objectB, int comparison_type) { VectorObject *vecA = NULL, *vecB = NULL; int result = 0; @@ -1727,7 +1790,7 @@ PyTypeObject vector_Type = { 0, /* long tp_dictoffset; */ NULL, /* initproc tp_init; */ NULL, /* allocfunc tp_alloc; */ - NULL, /* newfunc tp_new; */ + Vector_new, /* newfunc tp_new; */ /* Low-level free-memory routine */ NULL, /* freefunc tp_free; */ /* For PyObject_IS_GC */ @@ -1785,7 +1848,7 @@ PyObject *newVectorObject(float *vec, int size, int type) ####################################################################### ----------------------------Vector.negate() -------------------- set the vector to it's negative -x, -y, -z */ -PyObject *Vector_Negate(VectorObject * self) +static PyObject *Vector_Negate(VectorObject * self) { int i; for(i = 0; i < self->size; i++) { diff --git a/source/blender/python/generic/vector.h b/source/blender/python/generic/vector.h index 930e987fcc7..d2eb826ef10 100644 --- a/source/blender/python/generic/vector.h +++ b/source/blender/python/generic/vector.h @@ -45,17 +45,6 @@ typedef struct { } VectorObject; /*prototypes*/ -PyObject *Vector_Zero( VectorObject * self ); -PyObject *Vector_Normalize( VectorObject * self ); -PyObject *Vector_Negate( VectorObject * self ); -PyObject *Vector_Resize2D( VectorObject * self ); -PyObject *Vector_Resize3D( VectorObject * self ); -PyObject *Vector_Resize4D( VectorObject * self ); -PyObject *Vector_ToTrackQuat( VectorObject * self, PyObject * args ); -PyObject *Vector_Reflect( VectorObject * self, PyObject * value ); -PyObject *Vector_Cross( VectorObject * self, VectorObject * value ); -PyObject *Vector_Dot( VectorObject * self, VectorObject * value ); -PyObject *Vector_copy( VectorObject * self ); PyObject *newVectorObject(float *vec, int size, int type); #endif /* EXPP_vector_h */ |