BPY: fixed iteration over and slicing of multidim. arrays.
authorArystanbek Dyussenov <arystan.d@gmail.com>
Wed, 20 Jan 2010 14:06:38 +0000 (14:06 +0000)
committerArystanbek Dyussenov <arystan.d@gmail.com>
Wed, 20 Jan 2010 14:06:38 +0000 (14:06 +0000)
release/scripts/io/export_fbx.py
release/scripts/io/export_obj.py
release/scripts/io/export_x3d.py
source/blender/python/intern/bpy_array.c
source/blender/python/intern/bpy_rna.c
source/blender/python/intern/bpy_rna.h

index ffd7c3f3efa6f6141eac8cc366d53931bd5b8604..7a69659d16438b319693c47aef232c88396bd71a 100644 (file)
@@ -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))
index 7c4c83c53c7132f846de6ff92646d0bea8b4f7e0..4f3212fa72531d01800e0ede783b0bbf486d0fb6 100644 (file)
@@ -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
index c492c4a6b1558ee1f886659f40c98362b6d6fc6e..44032a0c733da7303c5eb5896b2b2b0def0c0f15 100644 (file)
@@ -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:
index 76c9a0f6e11b8a51e5308eef7d5f2617fbc8795d..5afcae8f2ed383dcf7be4a91a69c1dbd491d315e 100644 (file)
@@ -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;
index 722968c9b3135b41c1765db27b64da03ad07cc2e..97a0dcae290209425748ea8c4792b695aaa15579 100644 (file)
@@ -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 */
index 01602c5a863ec0b7854893266cd908fae2e6f225..48eedd1d5b254a4eac9c4e87d957c40614588600 100644 (file)
@@ -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);