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)

_______________________________________________
Bf-blender-cvs mailing list
[email protected]
http://lists.blender.org/mailman/listinfo/bf-blender-cvs

Reply via email to