[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [43067] trunk/blender/source/blender/ python/mathutils/mathutils_Matrix.c: slice and iterator access for matrix. col/row so you can do...

Campbell Barton ideasman42 at gmail.com
Mon Jan 2 10:04:48 CET 2012


Revision: 43067
          http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=43067
Author:   campbellbarton
Date:     2012-01-02 09:04:37 +0000 (Mon, 02 Jan 2012)
Log Message:
-----------
slice and iterator access for matrix.col/row so you can do...

  a, b = mat.col[0:2]

  and...

  for a in mat.col: ...

Modified Paths:
--------------
    trunk/blender/source/blender/python/mathutils/mathutils_Matrix.c

Modified: trunk/blender/source/blender/python/mathutils/mathutils_Matrix.c
===================================================================
--- trunk/blender/source/blender/python/mathutils/mathutils_Matrix.c	2012-01-02 06:53:09 UTC (rev 43066)
+++ trunk/blender/source/blender/python/mathutils/mathutils_Matrix.c	2012-01-02 09:04:37 UTC (rev 43067)
@@ -2409,13 +2409,13 @@
 	return 0;
 }
 
-int MatrixAccess_clear(MatrixAccessObject *self)
+static int MatrixAccess_clear(MatrixAccessObject *self)
 {
 	Py_CLEAR(self->matrix_user);
 	return 0;
 }
 
-void MatrixAccess_dealloc(MatrixAccessObject *self)
+static void MatrixAccess_dealloc(MatrixAccessObject *self)
 {
 	if (self->matrix_user) {
 		PyObject_GC_UnTrack(self);
@@ -2434,6 +2434,38 @@
 	            self->matrix_user->num_col;
 }
 
+static PyObject *MatrixAccess_slice(MatrixAccessObject *self, int begin, int end)
+{
+	PyObject *tuple;
+	int count;
+
+	/* row/col access */
+	MatrixObject *matrix_user = self->matrix_user;
+	int matrix_access_len;
+	PyObject *(*Matrix_item_new)(MatrixObject *, int);
+
+	if (self->type == MAT_ACCESS_ROW) {
+		matrix_access_len = matrix_user->num_row;
+		Matrix_item_new = Matrix_item_row;
+	}
+	else { /* MAT_ACCESS_ROW */
+		matrix_access_len = matrix_user->num_col;
+		Matrix_item_new = Matrix_item_col;
+	}
+
+	CLAMP(begin, 0, matrix_access_len);
+	if (end < 0) end = (matrix_access_len + 1) + end;
+	CLAMP(end, 0, matrix_access_len);
+	begin = MIN2(begin, end);
+
+	tuple = PyTuple_New(end - begin);
+	for (count = begin; count < end; count++) {
+		PyTuple_SET_ITEM(tuple, count - begin, Matrix_item_new(matrix_user, count));
+	}
+
+	return tuple;
+}
+
 static PyObject *MatrixAccess_subscript(MatrixAccessObject *self, PyObject *item)
 {
 	MatrixObject *matrix_user = self->matrix_user;
@@ -2454,7 +2486,24 @@
 			return Matrix_item_col(matrix_user, i);
 		}
 	}
-	/* TODO, slice */
+	else if (PySlice_Check(item)) {
+		Py_ssize_t start, stop, step, slicelength;
+
+		if (PySlice_GetIndicesEx((void *)item, MatrixAccess_len(self), &start, &stop, &step, &slicelength) < 0)
+			return NULL;
+
+		if (slicelength <= 0) {
+			return PyTuple_New(0);
+		}
+		else if (step == 1) {
+			return MatrixAccess_slice(self, start, stop);
+		}
+		else {
+			PyErr_SetString(PyExc_IndexError,
+			                "slice steps not supported with matrix accessors");
+			return NULL;
+		}
+	}
 	else {
 		PyErr_Format(PyExc_TypeError,
 		             "matrix indices must be integers, not %.200s",
@@ -2493,7 +2542,23 @@
 	}
 }
 
+static PyObject *MatrixAccess_iter(MatrixAccessObject *self)
+{
+	/* Try get values from a collection */
+	PyObject *ret;
+	PyObject *iter = NULL;
+	ret = MatrixAccess_slice(self, 0, MATRIX_MAX_DIM);
 
+	/* we know this is a tuple so no need to PyIter_Check
+	 * otherwise it could be NULL (unlikely) if conversion failed */
+	if (ret) {
+		iter = PyObject_GetIter(ret);
+		Py_DECREF(ret);
+	}
+
+	return iter;
+}
+
 static PyMappingMethods MatrixAccess_AsMapping = {
 	(lenfunc)MatrixAccess_len,
 	(binaryfunc)MatrixAccess_subscript,
@@ -2525,6 +2590,8 @@
 	(traverseproc)MatrixAccess_traverse,	//tp_traverse
 	(inquiry)MatrixAccess_clear,	//tp_clear
 	NULL /* (richcmpfunc)MatrixAccess_richcmpr */ /* TODO*/, /*tp_richcompare*/
+	0,									/*tp_weaklistoffset*/
+	(getiterfunc)MatrixAccess_iter, /* getiterfunc tp_iter; */
 };
 
 static PyObject *MatrixAccess_CreatePyObject(MatrixObject *matrix, const eMatrixAccess_t type)




More information about the Bf-blender-cvs mailing list