[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