[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [21287] branches/blender2.5/blender/source /blender/python: slice support working in py3 for Vector and Matrix types.

Campbell Barton ideasman42 at gmail.com
Wed Jul 1 15:31:37 CEST 2009


Revision: 21287
          http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=21287
Author:   campbellbarton
Date:     2009-07-01 15:31:36 +0200 (Wed, 01 Jul 2009)

Log Message:
-----------
slice support working in py3 for Vector and Matrix types.
Added slice to PyRNA collections and arrays (py3 only).

eg.
some_verts = mesh.verts[0:10]
some_rna_array[4:-1] = [0,1,2,3]

Collections dont support assignment, when assigning slices, resizing the array isnt support like with python lists.

Modified Paths:
--------------
    branches/blender2.5/blender/source/blender/python/generic/matrix.c
    branches/blender2.5/blender/source/blender/python/generic/vector.c
    branches/blender2.5/blender/source/blender/python/intern/bpy_rna.c

Modified: branches/blender2.5/blender/source/blender/python/generic/matrix.c
===================================================================
--- branches/blender2.5/blender/source/blender/python/generic/matrix.c	2009-07-01 13:24:03 UTC (rev 21286)
+++ branches/blender2.5/blender/source/blender/python/generic/matrix.c	2009-07-01 13:31:36 UTC (rev 21287)
@@ -760,8 +760,7 @@
 }
 /*----------------------------object[z:y]------------------------
   sequence slice (set)*/
-static int Matrix_ass_slice(MatrixObject * self, int begin, int end,
-			     PyObject * seq)
+static int Matrix_ass_slice(MatrixObject * self, int begin, int end, PyObject * seq)
 {
 	int i, x, y, size, sub_size = 0;
 	float mat[16], f;
@@ -999,7 +998,84 @@
 };
 
 
+
 #if (PY_VERSION_HEX >= 0x03000000)
+static PyObject *Matrix_subscript(MatrixObject* self, PyObject* item)
+{
+	if (PyIndex_Check(item)) {
+		Py_ssize_t i;
+		i = PyNumber_AsSsize_t(item, PyExc_IndexError);
+		if (i == -1 && PyErr_Occurred())
+			return NULL;
+		if (i < 0)
+			i += self->rowSize;
+		return Matrix_item(self, i);
+	} else if (PySlice_Check(item)) {
+		Py_ssize_t start, stop, step, slicelength;
+
+		if (PySlice_GetIndicesEx((PySliceObject*)item, self->rowSize, &start, &stop, &step, &slicelength) < 0)
+			return NULL;
+
+		if (slicelength <= 0) {
+			return PyList_New(0);
+		}
+		else if (step == 1) {
+			return Matrix_slice(self, start, stop);
+		}
+		else {
+			PyErr_SetString(PyExc_TypeError, "slice steps not supported with matricies");
+			return NULL;
+		}
+	}
+	else {
+		PyErr_Format(PyExc_TypeError,
+			     "vector indices must be integers, not %.200s",
+			     item->ob_type->tp_name);
+		return NULL;
+	}
+}
+
+static int Matrix_ass_subscript(MatrixObject* self, PyObject* item, PyObject* value)
+{
+	if (PyIndex_Check(item)) {
+		Py_ssize_t i = PyNumber_AsSsize_t(item, PyExc_IndexError);
+		if (i == -1 && PyErr_Occurred())
+			return -1;
+		if (i < 0)
+			i += self->rowSize;
+		return Matrix_ass_item(self, i, value);
+	}
+	else if (PySlice_Check(item)) {
+		Py_ssize_t start, stop, step, slicelength;
+
+		if (PySlice_GetIndicesEx((PySliceObject*)item, self->rowSize, &start, &stop, &step, &slicelength) < 0)
+			return -1;
+
+		if (step == 1)
+			return Matrix_ass_slice(self, start, stop, value);
+		else {
+			PyErr_SetString(PyExc_TypeError, "slice steps not supported with matricies");
+			return -1;
+		}
+	}
+	else {
+		PyErr_Format(PyExc_TypeError,
+			     "matrix indices must be integers, not %.200s",
+			     item->ob_type->tp_name);
+		return -1;
+	}
+}
+
+static PyMappingMethods Matrix_AsMapping = {
+	(lenfunc)Matrix_len,
+	(binaryfunc)Matrix_subscript,
+	(objobjargproc)Matrix_ass_subscript
+};
+#endif /*  (PY_VERSION_HEX >= 0x03000000) */
+
+
+
+#if (PY_VERSION_HEX >= 0x03000000)
 static PyNumberMethods Matrix_NumMethods = {
 		(binaryfunc)	Matrix_add,	/*nb_add*/
 		(binaryfunc)	Matrix_sub,	/*nb_subtract*/
@@ -1106,7 +1182,7 @@
 	(reprfunc) Matrix_repr,			/*tp_repr*/
 	&Matrix_NumMethods,				/*tp_as_number*/
 	&Matrix_SeqMethods,				/*tp_as_sequence*/
-	0,								/*tp_as_mapping*/
+	&Matrix_AsMapping,				/*tp_as_mapping*/
 	0,								/*tp_hash*/
 	0,								/*tp_call*/
 	0,								/*tp_str*/

Modified: branches/blender2.5/blender/source/blender/python/generic/vector.c
===================================================================
--- branches/blender2.5/blender/source/blender/python/generic/vector.c	2009-07-01 13:24:03 UTC (rev 21286)
+++ branches/blender2.5/blender/source/blender/python/generic/vector.c	2009-07-01 13:31:36 UTC (rev 21287)
@@ -1051,16 +1051,100 @@
 		Py_RETURN_FALSE;
 	}
 }
+
 /*-----------------PROTCOL DECLARATIONS--------------------------*/
 static PySequenceMethods Vector_SeqMethods = {
 	(inquiry) Vector_len,						/* sq_length */
 	(binaryfunc) 0,								/* sq_concat */
-	(ssizeargfunc) 0,								/* sq_repeat */
+	(ssizeargfunc) 0,							/* sq_repeat */
 	(ssizeargfunc) Vector_item,					/* sq_item */
-	(ssizessizeargfunc) Vector_slice,				/* sq_slice */
+#if (PY_VERSION_HEX < 0x03000000)
+	(ssizessizeargfunc) Vector_slice,			/* sq_slice */ /* PY2 ONLY */
+#else
+	NULL,
+#endif
 	(ssizeobjargproc) Vector_ass_item,			/* sq_ass_item */
-	(ssizessizeobjargproc) Vector_ass_slice,		/* sq_ass_slice */
+#if (PY_VERSION_HEX < 0x03000000)
+	(ssizessizeobjargproc) Vector_ass_slice,	/* sq_ass_slice */ /* PY2 ONLY */
+#else
+	NULL,
+#endif
 };
+
+
+#if (PY_VERSION_HEX >= 0x03000000)
+static PyObject *Vector_subscript(VectorObject* self, PyObject* item)
+{
+	if (PyIndex_Check(item)) {
+		Py_ssize_t i;
+		i = PyNumber_AsSsize_t(item, PyExc_IndexError);
+		if (i == -1 && PyErr_Occurred())
+			return NULL;
+		if (i < 0)
+			i += self->size;
+		return Vector_item(self, i);
+	} else if (PySlice_Check(item)) {
+		Py_ssize_t start, stop, step, slicelength;
+
+		if (PySlice_GetIndicesEx((PySliceObject*)item, self->size, &start, &stop, &step, &slicelength) < 0)
+			return NULL;
+
+		if (slicelength <= 0) {
+			return PyList_New(0);
+		}
+		else if (step == 1) {
+			return Vector_slice(self, start, stop);
+		}
+		else {
+			PyErr_SetString(PyExc_TypeError, "slice steps not supported with vectors");
+			return NULL;
+		}
+	}
+	else {
+		PyErr_Format(PyExc_TypeError,
+			     "vector indices must be integers, not %.200s",
+			     item->ob_type->tp_name);
+		return NULL;
+	}
+}
+
+static int Vector_ass_subscript(VectorObject* self, PyObject* item, PyObject* value)
+{
+	if (PyIndex_Check(item)) {
+		Py_ssize_t i = PyNumber_AsSsize_t(item, PyExc_IndexError);
+		if (i == -1 && PyErr_Occurred())
+			return -1;
+		if (i < 0)
+			i += self->size;
+		return Vector_ass_item(self, i, value);
+	}
+	else if (PySlice_Check(item)) {
+		Py_ssize_t start, stop, step, slicelength;
+
+		if (PySlice_GetIndicesEx((PySliceObject*)item, self->size, &start, &stop, &step, &slicelength) < 0)
+			return -1;
+
+		if (step == 1)
+			return Vector_ass_slice(self, start, stop, value);
+		else {
+			PyErr_SetString(PyExc_TypeError, "slice steps not supported with vectors");
+			return -1;
+		}
+	}
+	else {
+		PyErr_Format(PyExc_TypeError,
+			     "vector indices must be integers, not %.200s",
+			     item->ob_type->tp_name);
+		return -1;
+	}
+}
+
+static PyMappingMethods Vector_AsMapping = {
+	(lenfunc)Vector_len,
+	(binaryfunc)Vector_subscript,
+	(objobjargproc)Vector_ass_subscript
+};
+#endif /*  (PY_VERSION_HEX >= 0x03000000) */
  
 #if (PY_VERSION_HEX >= 0x03000000)
 static PyNumberMethods Vector_NumMethods = {
@@ -1813,7 +1897,7 @@
 
 	&Vector_NumMethods,                       /* PyNumberMethods *tp_as_number; */
 	&Vector_SeqMethods,                       /* PySequenceMethods *tp_as_sequence; */
-	NULL,                       /* PyMappingMethods *tp_as_mapping; */
+	&Vector_AsMapping,                       /* PyMappingMethods *tp_as_mapping; */
 
 	/* More standard operations (here for binary compatibility) */
 

Modified: branches/blender2.5/blender/source/blender/python/intern/bpy_rna.c
===================================================================
--- branches/blender2.5/blender/source/blender/python/intern/bpy_rna.c	2009-07-01 13:24:03 UTC (rev 21286)
+++ branches/blender2.5/blender/source/blender/python/intern/bpy_rna.c	2009-07-01 13:31:36 UTC (rev 21287)
@@ -35,6 +35,7 @@
 #include "RNA_define.h" /* for defining our own rna */
 
 #include "MEM_guardedalloc.h"
+#include "BKE_utildefines.h"
 #include "BKE_context.h"
 #include "BKE_global.h" /* evil G.* */
 #include "BKE_report.h"
@@ -820,108 +821,246 @@
 	return len;
 }
 
-static PyObject *pyrna_prop_subscript( BPy_PropertyRNA * self, PyObject *key )
+/* internal use only */
+static PyObject *prop_subscript_collection_int(BPy_PropertyRNA * self, int keynum)
 {
-	PyObject *ret;
 	PointerRNA newptr;
-	int keynum = 0;
-	char *keyname = NULL;
-	
+
+	if(keynum < 0) keynum += RNA_property_collection_length(&self->ptr, self->prop);
+
+	if(RNA_property_collection_lookup_int(&self->ptr, self->prop, keynum, &newptr))
+		return pyrna_struct_CreatePyObject(&newptr);
+
+	PyErr_SetString(PyExc_IndexError, "out of range");
+	return NULL;
+}
+static PyObject *prop_subscript_array_int(BPy_PropertyRNA * self, int keynum)
+{
+	int len= RNA_property_array_length(self->prop);
+
+	if(keynum < 0) keynum += len;
+
+	if(keynum >= 0 && keynum < len)
+		return pyrna_prop_to_py_index(&self->ptr, self->prop, keynum);
+
+	PyErr_SetString(PyExc_IndexError, "out of range");
+	return NULL;
+}
+
+static PyObject *prop_subscript_collection_str(BPy_PropertyRNA * self, char *keyname)
+{
+	PointerRNA newptr;
+	if(RNA_property_collection_lookup_string(&self->ptr, self->prop, keyname, &newptr))
+		return pyrna_struct_CreatePyObject(&newptr);
+
+	PyErr_SetString(PyExc_KeyError, "key not found");
+	return NULL;
+}
+/* static PyObject *prop_subscript_array_str(BPy_PropertyRNA * self, char *keyname) */
+
+
+
+
+#if PY_VERSION_HEX >= 0x03000000
+static PyObject *prop_subscript_collection_slice(BPy_PropertyRNA * self, int start, int stop)
+{
+	PointerRNA newptr;
+	PyObject *list = PyList_New(stop - start);
+	int count;
+
+	start = MIN2(start,stop); /* values are clamped from  */
+
+	for(count = start; count < stop; count++) {
+		if(RNA_property_collection_lookup_int(&self->ptr, self->prop, count - start, &newptr)) {
+			PyList_SetItem(list, count - start, pyrna_struct_CreatePyObject(&newptr));
+		}
+		else {
+			Py_DECREF(list);
+
+			PyErr_SetString(PyExc_RuntimeError, "error getting an rna struct from a collection");
+			return NULL;
+		}
+	}
+
+	return list;
+}
+static PyObject *prop_subscript_array_slice(BPy_PropertyRNA * self, int start, int stop)
+{
+	PyObject *list = PyList_New(stop - start);
+	int count;
+
+	start = MIN2(start,stop); /* values are clamped from PySlice_GetIndicesEx */
+
+	for(count = start; count < stop; count++)
+		PyList_SetItem(list, count - start, pyrna_prop_to_py_index(&self->ptr, self->prop, count));
+
+	return list;
+}
+#endif
+
+static PyObject *prop_subscript_collection(BPy_PropertyRNA * self, PyObject *key)
+{
 	if (PyUnicode_Check(key)) {
-		keyname = _PyUnicode_AsString(key);
-	} else if (PyLong_Check(key)) {
-		keynum = PyLong_AsSsize_t(key);
-	} else {
+		return prop_subscript_collection_str(self, _PyUnicode_AsString(key));
+	}
+	else if (PyLong_Check(key)) {
+		return prop_subscript_collection_int(self, PyLong_AsSsize_t(key));
+	}
+#if PY_VERSION_HEX >= 0x03000000
+	else if (PySlice_Check(key)) {
+		int len= RNA_property_collection_length(&self->ptr, self->prop);
+		Py_ssize_t start, stop, step, slicelength;
+

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list