diff options
author | Arystanbek Dyussenov <arystan.d@gmail.com> | 2010-01-20 17:06:38 +0300 |
---|---|---|
committer | Arystanbek Dyussenov <arystan.d@gmail.com> | 2010-01-20 17:06:38 +0300 |
commit | 9790647ce6f0b99834e7199dd1ce1ef37a0c28ca (patch) | |
tree | 188707d95e7cfc1141c4d9c2a6630d03a9106247 /source/blender/python/intern | |
parent | e7686b4cdb41b233509be439609f22f9d67149ce (diff) |
BPY: fixed iteration over and slicing of multidim. arrays.
Diffstat (limited to 'source/blender/python/intern')
-rw-r--r-- | source/blender/python/intern/bpy_array.c | 26 | ||||
-rw-r--r-- | source/blender/python/intern/bpy_rna.c | 97 | ||||
-rw-r--r-- | source/blender/python/intern/bpy_rna.h | 2 |
3 files changed, 68 insertions, 57 deletions
diff --git a/source/blender/python/intern/bpy_array.c b/source/blender/python/intern/bpy_array.c index 76c9a0f6e11..5afcae8f2ed 100644 --- a/source/blender/python/intern/bpy_array.c +++ b/source/blender/python/intern/bpy_array.c @@ -457,14 +457,16 @@ static PyObject *pyrna_py_from_array_internal(PointerRNA *ptr, PropertyRNA *prop } #endif -PyObject *pyrna_py_from_array_index(BPy_PropertyRNA *self, int index) +PyObject *pyrna_py_from_array_index(BPy_PropertyRNA *self, PointerRNA *ptr, PropertyRNA *prop, int index) { - int totdim, i, len; - int dimsize[MAX_ARRAY_DIMENSION]; + int totdim, arraydim, arrayoffset, dimsize[MAX_ARRAY_DIMENSION], i, len; BPy_PropertyRNA *ret= NULL; + arraydim= self ? self->arraydim : 0; + arrayoffset = self ? self->arrayoffset : 0; + /* just in case check */ - len= RNA_property_multi_array_length(&self->ptr, self->prop, self->arraydim); + len= RNA_property_multi_array_length(ptr, prop, arraydim); if (index >= len || index < 0) { /* this shouldn't happen because higher level funcs must check for invalid index */ if (G.f & G_DEBUG) printf("pyrna_py_from_array_index: invalid index %d for array with length=%d\n", index, len); @@ -473,11 +475,11 @@ PyObject *pyrna_py_from_array_index(BPy_PropertyRNA *self, int index) return NULL; } - totdim= RNA_property_array_dimension(&self->ptr, self->prop, dimsize); + totdim= RNA_property_array_dimension(ptr, prop, dimsize); - if (self->arraydim + 1 < totdim) { - ret= (BPy_PropertyRNA*)pyrna_prop_CreatePyObject(&self->ptr, self->prop); - ret->arraydim= self->arraydim + 1; + if (arraydim + 1 < totdim) { + ret= (BPy_PropertyRNA*)pyrna_prop_CreatePyObject(ptr, prop); + ret->arraydim= arraydim + 1; /* arr[3][4][5] @@ -487,14 +489,14 @@ PyObject *pyrna_py_from_array_index(BPy_PropertyRNA *self, int index) x = arr[2][3] index = offset + 3 * 5 */ - for (i= self->arraydim + 1; i < totdim; i++) + for (i= arraydim + 1; i < totdim; i++) index *= dimsize[i]; - ret->arrayoffset= self->arrayoffset + index; + ret->arrayoffset= arrayoffset + index; } else { - index = self->arrayoffset + index; - ret= (BPy_PropertyRNA*)pyrna_array_item(&self->ptr, self->prop, index); + index = arrayoffset + index; + ret= (BPy_PropertyRNA*)pyrna_array_item(ptr, prop, index); } return (PyObject*)ret; diff --git a/source/blender/python/intern/bpy_rna.c b/source/blender/python/intern/bpy_rna.c index 722968c9b31..97a0dcae290 100644 --- a/source/blender/python/intern/bpy_rna.c +++ b/source/blender/python/intern/bpy_rna.c @@ -55,7 +55,7 @@ #include "../generic/Mathutils.h" /* so we can have mathutils callbacks */ #include "../generic/IDProp.h" /* for IDprop lookups */ -static PyObject *prop_subscript_array_slice(PointerRNA *ptr, PropertyRNA *prop, int start, int stop, int length); +static PyObject *prop_subscript_array_slice(BPy_PropertyRNA *self, PointerRNA *ptr, PropertyRNA *prop, int start, int stop, int length); /* bpyrna vector/euler/quat callbacks */ static int mathutils_rna_array_cb_index= -1; /* index for our callbacks */ @@ -240,7 +240,7 @@ PyObject *pyrna_math_object_from_array(PointerRNA *ptr, PropertyRNA *prop) if(is_thick) { /* this is an array we cant reference (since its not thin wrappable) * and cannot be coerced into a mathutils type, so return as a list */ - ret = prop_subscript_array_slice(ptr, prop, 0, len, len); + ret = prop_subscript_array_slice(NULL, ptr, prop, 0, len, len); } else { ret = pyrna_prop_CreatePyObject(ptr, prop); /* owned by the Mathutils PyObject */ } @@ -878,7 +878,7 @@ int pyrna_py_to_prop(PointerRNA *ptr, PropertyRNA *prop, void *data, PyObject *v static PyObject * pyrna_prop_to_py_index(BPy_PropertyRNA *self, int index) { - return pyrna_py_from_array_index(self, index); + return pyrna_py_from_array_index(self, &self->ptr, self->prop, index); } static int pyrna_py_to_prop_index(BPy_PropertyRNA *self, int index, PyObject *value) @@ -1035,65 +1035,74 @@ static PyObject *prop_subscript_collection_slice(PointerRNA *ptr, PropertyRNA *p * note: could also use pyrna_prop_to_py_index(self, count) in a loop but its a lot slower * since at the moment it reads (and even allocates) the entire array for each index. */ -static PyObject *prop_subscript_array_slice(PointerRNA *ptr, PropertyRNA *prop, int start, int stop, int length) +static PyObject *prop_subscript_array_slice(BPy_PropertyRNA *self, PointerRNA *ptr, PropertyRNA *prop, int start, int stop, int length) { + int count, totdim; + PyObject *list = PyList_New(stop - start); - int count; - switch (RNA_property_type(prop)) { + totdim = RNA_property_array_dimension(ptr, prop, NULL); + + if (totdim > 1) { + for (count = start; count < stop; count++) + PyList_SET_ITEM(list, count - start, pyrna_prop_to_py_index(self, count)); + } + else { + switch (RNA_property_type(prop)) { case PROP_FLOAT: - { - float values_stack[PYRNA_STACK_ARRAY]; - float *values; - if(length > PYRNA_STACK_ARRAY) { values= PyMem_MALLOC(sizeof(float) * length); } - else { values= values_stack; } - RNA_property_float_get_array(ptr, prop, values); + { + float values_stack[PYRNA_STACK_ARRAY]; + float *values; + if(length > PYRNA_STACK_ARRAY) { values= PyMem_MALLOC(sizeof(float) * length); } + else { values= values_stack; } + RNA_property_float_get_array(ptr, prop, values); - for(count=start; count<stop; count++) - PyList_SET_ITEM(list, count-start, PyFloat_FromDouble(values[count])); + for(count=start; count<stop; count++) + PyList_SET_ITEM(list, count-start, PyFloat_FromDouble(values[count])); - if(values != values_stack) { - PyMem_FREE(values); + if(values != values_stack) { + PyMem_FREE(values); + } + break; } - break; - } case PROP_BOOLEAN: - { - int values_stack[PYRNA_STACK_ARRAY]; - int *values; - if(length > PYRNA_STACK_ARRAY) { values= PyMem_MALLOC(sizeof(int) * length); } - else { values= values_stack; } + { + int values_stack[PYRNA_STACK_ARRAY]; + int *values; + if(length > PYRNA_STACK_ARRAY) { values= PyMem_MALLOC(sizeof(int) * length); } + else { values= values_stack; } - RNA_property_boolean_get_array(ptr, prop, values); - for(count=start; count<stop; count++) - PyList_SET_ITEM(list, count-start, PyBool_FromLong(values[count])); + RNA_property_boolean_get_array(ptr, prop, values); + for(count=start; count<stop; count++) + PyList_SET_ITEM(list, count-start, PyBool_FromLong(values[count])); - if(values != values_stack) { - PyMem_FREE(values); + if(values != values_stack) { + PyMem_FREE(values); + } + break; } - break; - } case PROP_INT: - { - int values_stack[PYRNA_STACK_ARRAY]; - int *values; - if(length > PYRNA_STACK_ARRAY) { values= PyMem_MALLOC(sizeof(int) * length); } - else { values= values_stack; } + { + int values_stack[PYRNA_STACK_ARRAY]; + int *values; + if(length > PYRNA_STACK_ARRAY) { values= PyMem_MALLOC(sizeof(int) * length); } + else { values= values_stack; } - RNA_property_int_get_array(ptr, prop, values); - for(count=start; count<stop; count++) - PyList_SET_ITEM(list, count-start, PyLong_FromSsize_t(values[count])); + RNA_property_int_get_array(ptr, prop, values); + for(count=start; count<stop; count++) + PyList_SET_ITEM(list, count-start, PyLong_FromSsize_t(values[count])); - if(values != values_stack) { - PyMem_FREE(values); + if(values != values_stack) { + PyMem_FREE(values); + } + break; } - break; - } default: /* probably will never happen */ PyErr_SetString(PyExc_TypeError, "not an array type"); Py_DECREF(list); list= NULL; + } } return list; } @@ -1156,7 +1165,7 @@ static PyObject *prop_subscript_array(BPy_PropertyRNA *self, PyObject *key) return PyList_New(0); } else if (step == 1) { - return prop_subscript_array_slice(&self->ptr, self->prop, start, stop, len); + return prop_subscript_array_slice(self, &self->ptr, self->prop, start, stop, len); } else { PyErr_SetString(PyExc_TypeError, "slice steps not supported with rna"); @@ -2511,7 +2520,7 @@ PyObject *pyrna_prop_iter(BPy_PropertyRNA *self) if(RNA_property_array_check(&self->ptr, self->prop)) { int len= pyrna_prop_array_length(self); - ret = prop_subscript_array_slice(&self->ptr, self->prop, 0, len, len); + ret = prop_subscript_array_slice(self, &self->ptr, self->prop, 0, len, len); } else if ((ret = pyrna_prop_values(self))) { /* do nothing */ diff --git a/source/blender/python/intern/bpy_rna.h b/source/blender/python/intern/bpy_rna.h index 01602c5a863..48eedd1d5b2 100644 --- a/source/blender/python/intern/bpy_rna.h +++ b/source/blender/python/intern/bpy_rna.h @@ -94,7 +94,7 @@ int pyrna_py_to_array(PointerRNA *ptr, PropertyRNA *prop, char *param_data, PyOb int pyrna_py_to_array_index(PointerRNA *ptr, PropertyRNA *prop, int arraydim, int arrayoffset, int index, PyObject *py, const char *error_prefix); PyObject *pyrna_py_from_array(PointerRNA *ptr, PropertyRNA *prop); -PyObject *pyrna_py_from_array_index(BPy_PropertyRNA *self, int index); +PyObject *pyrna_py_from_array_index(BPy_PropertyRNA *self, PointerRNA *ptr, PropertyRNA *prop, int index); PyObject *pyrna_math_object_from_array(PointerRNA *ptr, PropertyRNA *prop); int pyrna_array_contains_py(PointerRNA *ptr, PropertyRNA *prop, PyObject *value); |