From 9790647ce6f0b99834e7199dd1ce1ef37a0c28ca Mon Sep 17 00:00:00 2001 From: Arystanbek Dyussenov Date: Wed, 20 Jan 2010 14:06:38 +0000 Subject: [PATCH] BPY: fixed iteration over and slicing of multidim. arrays. --- release/scripts/io/export_fbx.py | 2 +- release/scripts/io/export_obj.py | 2 +- release/scripts/io/export_x3d.py | 2 +- source/blender/python/intern/bpy_array.c | 26 ++++--- source/blender/python/intern/bpy_rna.c | 97 +++++++++++++----------- source/blender/python/intern/bpy_rna.h | 2 +- 6 files changed, 71 insertions(+), 60 deletions(-) diff --git a/release/scripts/io/export_fbx.py b/release/scripts/io/export_fbx.py index ffd7c3f3efa..7a69659d164 100644 --- a/release/scripts/io/export_fbx.py +++ b/release/scripts/io/export_fbx.py @@ -1753,7 +1753,7 @@ def write(filename, batch_objects = None, \ for uf in uvlayer.data: # for f in me.faces: # workaround, since uf.uv iteration is wrong atm - for uv in [uf.uv1, uf.uv2, uf.uv3, uf.uv4][:len(uf.uv)]: + for uv in uf.uv: # for uv in f.uv: if i==-1: file.write('%.6f,%.6f' % tuple(uv)) diff --git a/release/scripts/io/export_obj.py b/release/scripts/io/export_obj.py index 7c4c83c53c7..4f3212fa725 100644 --- a/release/scripts/io/export_obj.py +++ b/release/scripts/io/export_obj.py @@ -564,7 +564,7 @@ def write(filename, objects, scene, tface = uv_layer.data[f_index] # workaround, since tface.uv iteration is wrong atm - uvs = [tface.uv1, tface.uv2, tface.uv3, tface.uv4][:len(tface.uv)] + uvs = tface.uv # uvs = [tface.uv1, tface.uv2, tface.uv3] # # add another UV if it's a quad diff --git a/release/scripts/io/export_x3d.py b/release/scripts/io/export_x3d.py index c492c4a6b15..44032a0c733 100644 --- a/release/scripts/io/export_x3d.py +++ b/release/scripts/io/export_x3d.py @@ -617,7 +617,7 @@ class x3d_class: for face in mesh.active_uv_texture.data: # for face in mesh.faces: # workaround, since tface.uv iteration is wrong atm - uvs = [face.uv1, face.uv2, face.uv3, face.uv4][:len(face.uv)] + uvs = face.uv # uvs = [face.uv1, face.uv2, face.uv3, face.uv4] if face.verts[3] else [face.uv1, face.uv2, face.uv3] for uv in uvs: 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 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 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; countptr, 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);