From 0660078b8bb5eac6f81bd352505dc6f7d72e06c1 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sun, 9 Jan 2011 14:30:16 +0000 Subject: [PATCH] mathutils matrix initialization now matches other mathutils types. (should have made this change along with the others). Matrix([1, 2], [3, 4]) --> Matrix(([1, 2], [3, 4])) This is so adding initialization args works right. Also simplify initialization code (re-use slice assignment). --- .../blender/python/generic/mathutils_matrix.c | 92 ++++++------------- .../blender/python/generic/mathutils_matrix.h | 2 +- 2 files changed, 28 insertions(+), 66 deletions(-) diff --git a/source/blender/python/generic/mathutils_matrix.c b/source/blender/python/generic/mathutils_matrix.c index 35d58ceb255..4e33c312bf8 100644 --- a/source/blender/python/generic/mathutils_matrix.c +++ b/source/blender/python/generic/mathutils_matrix.c @@ -31,7 +31,7 @@ #include "BLI_blenlib.h" #include "BLI_utildefines.h" - +static int Matrix_ass_slice(MatrixObject * self, int begin, int end, PyObject *value); /* matrix vector callbacks */ int mathutils_matrix_vector_cb_index= -1; @@ -109,80 +109,42 @@ Mathutils_Callback mathutils_matrix_vector_cb = { //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; - if(kwds && PyDict_Size(kwds)) { PyErr_SetString(PyExc_TypeError, "mathutils.Matrix(): takes no keyword args"); return NULL; } - argSize = PyTuple_GET_SIZE(args); - if(argSize > MATRIX_MAX_DIM) { //bad arg nums - PyErr_SetString(PyExc_AttributeError, "mathutils.Matrix(): expects 0-4 numeric sequences of the same size"); - return NULL; - } else if (argSize == 0) { //return empty 4D matrix - return (PyObject *) newMatrixObject(NULL, 4, 4, Py_NEW, type); - }else if (argSize == 1){ - //copy constructor for matrix objects - argObject = PyTuple_GET_ITEM(args, 0); - if(MatrixObject_Check(argObject)){ - mat = (MatrixObject*)argObject; - if(!BaseMath_ReadCallback(mat)) - return NULL; + switch(PyTuple_GET_SIZE(args)) { + case 0: + return (PyObject *) newMatrixObject(NULL, 4, 4, Py_NEW, type); + case 1: + { + PyObject *arg= PyTuple_GET_ITEM(args, 0); - memcpy(matrix, mat->contigPtr, sizeof(float) * mat->rowSize * mat->colSize); - argSize = mat->rowSize; - seqSize = mat->colSize; - } - }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"); - return NULL; + const unsigned short row_size= PySequence_Size(arg); /* -1 is an error, size checks will accunt for this */ + + if(IN_RANGE_INCL(row_size, 2, 4)) { + PyObject *item= PySequence_GetItem(arg, 0); + const unsigned short col_size= PySequence_Size(item); + Py_XDECREF(item); + + if(IN_RANGE_INCL(col_size, 2, 4)) { + /* sane row & col size, new matrix and assign as slice */ + PyObject *matrix= newMatrixObject(NULL, row_size, col_size, Py_NEW, type); + if(Matrix_ass_slice((MatrixObject *)matrix, 0, INT_MAX, arg) == 0) { + return matrix; + } + else { /* matrix ok, slice assignment not */ + Py_DECREF(matrix); } } - seqSize = PySequence_Length(argObject); - }else{ //arg not a sequence - PyErr_SetString(PyExc_TypeError, "mathutils.Matrix(): expects 0-4 numeric sequences of the same size"); - 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"); - 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"); - 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"); - return NULL; - } - - matrix[(seqSize*i)+j]= scalar; } } } - return newMatrixObject(matrix, argSize, seqSize, Py_NEW, type); + + /* will overwrite error */ + PyErr_SetString(PyExc_TypeError, "mathutils.Matrix(): expects no args or 2-4 numeric sequences"); + return NULL; } /*-----------------------CLASS-METHODS----------------------------*/ @@ -1847,7 +1809,7 @@ self->matrix[1][1] = self->contigPtr[4] */ (i.e. it was allocated elsewhere by MEM_mallocN()) pass Py_NEW - if vector is not a WRAPPER and managed by PYTHON (i.e. it must be created here with PyMEM_malloc())*/ -PyObject *newMatrixObject(float *mat, int rowSize, int colSize, int type, PyTypeObject *base_type) +PyObject *newMatrixObject(float *mat, const unsigned short rowSize, const unsigned short colSize, int type, PyTypeObject *base_type) { MatrixObject *self; int x, row, col; diff --git a/source/blender/python/generic/mathutils_matrix.h b/source/blender/python/generic/mathutils_matrix.h index f1cce3a45a8..863cfeb5e05 100644 --- a/source/blender/python/generic/mathutils_matrix.h +++ b/source/blender/python/generic/mathutils_matrix.h @@ -49,7 +49,7 @@ 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 *newMatrixObject(float *mat, int rowSize, int colSize, int type, PyTypeObject *base_type); +PyObject *newMatrixObject(float *mat, const unsigned short rowSize, const unsigned short colSize, int type, PyTypeObject *base_type); PyObject *newMatrixObject_cb(PyObject *user, int rowSize, int colSize, int cb_type, int cb_subtype); extern int mathutils_matrix_vector_cb_index;