| 
									
										
										
										
											2011-02-23 10:52:22 +00:00
										 |  |  | /*
 | 
					
						
							| 
									
										
										
											
												Implemented dynamic and multidimensional array support in RNA.
Example code: http://www.pasteall.org/7332/c.
New API functions: http://www.pasteall.org/7330/c.
Maximum number of dimensions is currently limited to 3, but can be increased arbitrarily if needed.
What this means for ID property access:
* MeshFace.verts - dynamic array, size 3 or 4 depending on MFace.v4
* MeshTextureFace.uv - dynamic, 2-dimensional array, size depends on MFace.v4
* Object.matrix - 2-dimensional array
What this means for functions:
* more intuitive API possibility, for example:
  Mesh.add_vertices([(x, y, z), (x, y, z), ...])
  Mesh.add_faces([(1, 2, 3), (4, 5, 6), ...])
Python part is not complete yet, e.g. it is possible to:
MeshFace.verts = (1, 2, 3) # even if Mesh.verts is (1, 2, 3, 4) and vice-versa
MeshTextureFace.uv = [(0.0, 0.0)] * 4 # only if a corresponding MFace is a quad
but the following won't work:
MeshTextureFace.uv[3] = (0.0, 0.0) # setting uv[3] modifies MTFace.uv[1][0] instead of MTFace.uv[3]
											
										 
											2009-08-25 17:06:36 +00:00
										 |  |  |  * This program is free software; you can redistribute it and/or | 
					
						
							|  |  |  |  * modify it under the terms of the GNU General Public License | 
					
						
							|  |  |  |  * as published by the Free Software Foundation; either version 2 | 
					
						
							|  |  |  |  * of the License, or (at your option) any later version. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * This program is distributed in the hope that it will be useful, | 
					
						
							|  |  |  |  * but WITHOUT ANY WARRANTY; without even the implied warranty of | 
					
						
							|  |  |  |  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | 
					
						
							|  |  |  |  * GNU General Public License for more details. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * You should have received a copy of the GNU General Public License | 
					
						
							|  |  |  |  * along with this program; if not, write to the Free Software Foundation, | 
					
						
							| 
									
										
										
										
											2010-02-12 13:34:04 +00:00
										 |  |  |  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | 
					
						
							| 
									
										
										
											
												Implemented dynamic and multidimensional array support in RNA.
Example code: http://www.pasteall.org/7332/c.
New API functions: http://www.pasteall.org/7330/c.
Maximum number of dimensions is currently limited to 3, but can be increased arbitrarily if needed.
What this means for ID property access:
* MeshFace.verts - dynamic array, size 3 or 4 depending on MFace.v4
* MeshTextureFace.uv - dynamic, 2-dimensional array, size depends on MFace.v4
* Object.matrix - 2-dimensional array
What this means for functions:
* more intuitive API possibility, for example:
  Mesh.add_vertices([(x, y, z), (x, y, z), ...])
  Mesh.add_faces([(1, 2, 3), (4, 5, 6), ...])
Python part is not complete yet, e.g. it is possible to:
MeshFace.verts = (1, 2, 3) # even if Mesh.verts is (1, 2, 3, 4) and vice-versa
MeshTextureFace.uv = [(0.0, 0.0)] * 4 # only if a corresponding MFace is a quad
but the following won't work:
MeshTextureFace.uv[3] = (0.0, 0.0) # setting uv[3] modifies MTFace.uv[1][0] instead of MTFace.uv[3]
											
										 
											2009-08-25 17:06:36 +00:00
										 |  |  |  */ | 
					
						
							| 
									
										
										
										
											2011-02-27 20:10:08 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-02-18 08:08:12 +11:00
										 |  |  | /** \file
 | 
					
						
							|  |  |  |  * \ingroup pythonintern | 
					
						
							| 
									
										
										
										
											2011-11-05 08:21:12 +00:00
										 |  |  |  * | 
					
						
							|  |  |  |  * This file deals with array access for 'BPy_PropertyArrayRNA' from bpy_rna.c | 
					
						
							| 
									
										
										
										
											2011-02-27 20:10:08 +00:00
										 |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-02-14 04:15:25 +00:00
										 |  |  | #include <Python.h>
 | 
					
						
							| 
									
										
										
											
												Implemented dynamic and multidimensional array support in RNA.
Example code: http://www.pasteall.org/7332/c.
New API functions: http://www.pasteall.org/7330/c.
Maximum number of dimensions is currently limited to 3, but can be increased arbitrarily if needed.
What this means for ID property access:
* MeshFace.verts - dynamic array, size 3 or 4 depending on MFace.v4
* MeshTextureFace.uv - dynamic, 2-dimensional array, size depends on MFace.v4
* Object.matrix - 2-dimensional array
What this means for functions:
* more intuitive API possibility, for example:
  Mesh.add_vertices([(x, y, z), (x, y, z), ...])
  Mesh.add_faces([(1, 2, 3), (4, 5, 6), ...])
Python part is not complete yet, e.g. it is possible to:
MeshFace.verts = (1, 2, 3) # even if Mesh.verts is (1, 2, 3, 4) and vice-versa
MeshTextureFace.uv = [(0.0, 0.0)] * 4 # only if a corresponding MFace is a quad
but the following won't work:
MeshTextureFace.uv[3] = (0.0, 0.0) # setting uv[3] modifies MTFace.uv[1][0] instead of MTFace.uv[3]
											
										 
											2009-08-25 17:06:36 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-04-02 11:05:15 +02:00
										 |  |  | #include "CLG_log.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-14 17:23:40 +11:00
										 |  |  | #include "BLI_utildefines.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-03-02 04:51:43 +00:00
										 |  |  | #include "RNA_types.h"
 | 
					
						
							| 
									
										
										
										
											2012-10-26 18:06:14 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
											
												Implemented dynamic and multidimensional array support in RNA.
Example code: http://www.pasteall.org/7332/c.
New API functions: http://www.pasteall.org/7330/c.
Maximum number of dimensions is currently limited to 3, but can be increased arbitrarily if needed.
What this means for ID property access:
* MeshFace.verts - dynamic array, size 3 or 4 depending on MFace.v4
* MeshTextureFace.uv - dynamic, 2-dimensional array, size depends on MFace.v4
* Object.matrix - 2-dimensional array
What this means for functions:
* more intuitive API possibility, for example:
  Mesh.add_vertices([(x, y, z), (x, y, z), ...])
  Mesh.add_faces([(1, 2, 3), (4, 5, 6), ...])
Python part is not complete yet, e.g. it is possible to:
MeshFace.verts = (1, 2, 3) # even if Mesh.verts is (1, 2, 3, 4) and vice-versa
MeshTextureFace.uv = [(0.0, 0.0)] * 4 # only if a corresponding MFace is a quad
but the following won't work:
MeshTextureFace.uv[3] = (0.0, 0.0) # setting uv[3] modifies MTFace.uv[1][0] instead of MTFace.uv[3]
											
										 
											2009-08-25 17:06:36 +00:00
										 |  |  | #include "bpy_rna.h"
 | 
					
						
							| 
									
										
										
										
											2009-09-06 15:13:57 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-14 17:23:40 +11:00
										 |  |  | #include "MEM_guardedalloc.h"
 | 
					
						
							| 
									
										
										
										
											2014-05-01 07:21:08 +10:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-03-02 04:51:43 +00:00
										 |  |  | #include "RNA_access.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-04-02 11:05:15 +02:00
										 |  |  | #include "BPY_extern_clog.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-08-20 15:44:54 +10:00
										 |  |  | #include "../generic/py_capi_utils.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-12-22 08:44:08 +00:00
										 |  |  | #define USE_MATHUTILS
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #ifdef USE_MATHUTILS
 | 
					
						
							|  |  |  | #  include "../mathutils/mathutils.h" /* so we can have mathutils callbacks */
 | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-09-06 15:13:57 +00:00
										 |  |  | #define MAX_ARRAY_DIMENSION 10
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-03-08 15:33:28 +11:00
										 |  |  | struct ItemConvertArgData; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | typedef void (*ItemConvertFunc)(const struct ItemConvertArgData *arg, PyObject *, char *); | 
					
						
							| 
									
										
										
										
											2012-03-26 20:41:54 +00:00
										 |  |  | typedef int (*ItemTypeCheckFunc)(PyObject *); | 
					
						
							| 
									
										
										
											
												Implemented dynamic and multidimensional array support in RNA.
Example code: http://www.pasteall.org/7332/c.
New API functions: http://www.pasteall.org/7330/c.
Maximum number of dimensions is currently limited to 3, but can be increased arbitrarily if needed.
What this means for ID property access:
* MeshFace.verts - dynamic array, size 3 or 4 depending on MFace.v4
* MeshTextureFace.uv - dynamic, 2-dimensional array, size depends on MFace.v4
* Object.matrix - 2-dimensional array
What this means for functions:
* more intuitive API possibility, for example:
  Mesh.add_vertices([(x, y, z), (x, y, z), ...])
  Mesh.add_faces([(1, 2, 3), (4, 5, 6), ...])
Python part is not complete yet, e.g. it is possible to:
MeshFace.verts = (1, 2, 3) # even if Mesh.verts is (1, 2, 3, 4) and vice-versa
MeshTextureFace.uv = [(0.0, 0.0)] * 4 # only if a corresponding MFace is a quad
but the following won't work:
MeshTextureFace.uv[3] = (0.0, 0.0) # setting uv[3] modifies MTFace.uv[1][0] instead of MTFace.uv[3]
											
										 
											2009-08-25 17:06:36 +00:00
										 |  |  | typedef void (*RNA_SetArrayFunc)(PointerRNA *, PropertyRNA *, const char *); | 
					
						
							| 
									
										
										
										
											2009-09-06 15:13:57 +00:00
										 |  |  | typedef void (*RNA_SetIndexFunc)(PointerRNA *, PropertyRNA *, int index, void *); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-03-08 15:33:28 +11:00
										 |  |  | struct ItemConvertArgData { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   union { | 
					
						
							|  |  |  |     struct { | 
					
						
							|  |  |  |       int range[2]; | 
					
						
							|  |  |  |     } int_data; | 
					
						
							|  |  |  |     struct { | 
					
						
							|  |  |  |       float range[2]; | 
					
						
							|  |  |  |     } float_data; | 
					
						
							|  |  |  |   }; | 
					
						
							| 
									
										
										
										
											2016-03-08 15:33:28 +11:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /**
 | 
					
						
							|  |  |  |  * Callback and args needed to apply the value (clamp range for now) | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | typedef struct ItemConvert_FuncArg { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   ItemConvertFunc func; | 
					
						
							|  |  |  |   struct ItemConvertArgData arg; | 
					
						
							| 
									
										
										
										
											2016-03-08 15:33:28 +11:00
										 |  |  | } ItemConvert_FuncArg; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-09-06 15:13:57 +00:00
										 |  |  | /*
 | 
					
						
							| 
									
										
										
										
											2012-03-03 20:36:09 +00:00
										 |  |  |  * arr[3][4][5] | 
					
						
							|  |  |  |  *     0  1  2  <- dimension index | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
											
												Implemented dynamic and multidimensional array support in RNA.
Example code: http://www.pasteall.org/7332/c.
New API functions: http://www.pasteall.org/7330/c.
Maximum number of dimensions is currently limited to 3, but can be increased arbitrarily if needed.
What this means for ID property access:
* MeshFace.verts - dynamic array, size 3 or 4 depending on MFace.v4
* MeshTextureFace.uv - dynamic, 2-dimensional array, size depends on MFace.v4
* Object.matrix - 2-dimensional array
What this means for functions:
* more intuitive API possibility, for example:
  Mesh.add_vertices([(x, y, z), (x, y, z), ...])
  Mesh.add_faces([(1, 2, 3), (4, 5, 6), ...])
Python part is not complete yet, e.g. it is possible to:
MeshFace.verts = (1, 2, 3) # even if Mesh.verts is (1, 2, 3, 4) and vice-versa
MeshTextureFace.uv = [(0.0, 0.0)] * 4 # only if a corresponding MFace is a quad
but the following won't work:
MeshTextureFace.uv[3] = (0.0, 0.0) # setting uv[3] modifies MTFace.uv[1][0] instead of MTFace.uv[3]
											
										 
											2009-08-25 17:06:36 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-09-06 15:13:57 +00:00
										 |  |  | /*
 | 
					
						
							| 
									
										
										
										
											2012-03-03 20:36:09 +00:00
										 |  |  |  *  arr[2] = x | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  *  py_to_array_index(arraydim=0, arrayoffset=0, index=2) | 
					
						
							|  |  |  |  *      validate_array(lvalue_dim=0) | 
					
						
							|  |  |  |  *      ... make real index ... | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2009-09-06 15:13:57 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-12-26 12:26:11 +00:00
										 |  |  | /* arr[3] = x, self->arraydim is 0, lvalue_dim is 1 */ | 
					
						
							| 
									
										
										
										
											2019-04-29 19:59:13 +10:00
										 |  |  | /* Ensures that a python sequence has expected number of
 | 
					
						
							|  |  |  |  * items/sub-items and items are of desired type. */ | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | static int validate_array_type(PyObject *seq, | 
					
						
							|  |  |  |                                int dim, | 
					
						
							|  |  |  |                                int totdim, | 
					
						
							|  |  |  |                                int dimsize[], | 
					
						
							|  |  |  |                                const bool is_dynamic, | 
					
						
							|  |  |  |                                ItemTypeCheckFunc check_item_type, | 
					
						
							|  |  |  |                                const char *item_type_str, | 
					
						
							|  |  |  |                                const char *error_prefix) | 
					
						
							| 
									
										
										
											
												Implemented dynamic and multidimensional array support in RNA.
Example code: http://www.pasteall.org/7332/c.
New API functions: http://www.pasteall.org/7330/c.
Maximum number of dimensions is currently limited to 3, but can be increased arbitrarily if needed.
What this means for ID property access:
* MeshFace.verts - dynamic array, size 3 or 4 depending on MFace.v4
* MeshTextureFace.uv - dynamic, 2-dimensional array, size depends on MFace.v4
* Object.matrix - 2-dimensional array
What this means for functions:
* more intuitive API possibility, for example:
  Mesh.add_vertices([(x, y, z), (x, y, z), ...])
  Mesh.add_faces([(1, 2, 3), (4, 5, 6), ...])
Python part is not complete yet, e.g. it is possible to:
MeshFace.verts = (1, 2, 3) # even if Mesh.verts is (1, 2, 3, 4) and vice-versa
MeshTextureFace.uv = [(0.0, 0.0)] * 4 # only if a corresponding MFace is a quad
but the following won't work:
MeshTextureFace.uv[3] = (0.0, 0.0) # setting uv[3] modifies MTFace.uv[1][0] instead of MTFace.uv[3]
											
										 
											2009-08-25 17:06:36 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   Py_ssize_t i; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   /* not the last dimension */ | 
					
						
							|  |  |  |   if (dim + 1 < totdim) { | 
					
						
							|  |  |  |     /* check that a sequence contains dimsize[dim] items */ | 
					
						
							|  |  |  |     const int seq_size = PySequence_Size(seq); | 
					
						
							|  |  |  |     if (seq_size == -1) { | 
					
						
							|  |  |  |       PyErr_Format(PyExc_ValueError, | 
					
						
							|  |  |  |                    "%s sequence expected at dimension %d, not '%s'", | 
					
						
							|  |  |  |                    error_prefix, | 
					
						
							|  |  |  |                    dim + 1, | 
					
						
							|  |  |  |                    Py_TYPE(seq)->tp_name); | 
					
						
							|  |  |  |       return -1; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     for (i = 0; i < seq_size; i++) { | 
					
						
							|  |  |  |       Py_ssize_t item_seq_size; | 
					
						
							|  |  |  |       PyObject *item; | 
					
						
							|  |  |  |       bool ok = true; | 
					
						
							|  |  |  |       item = PySequence_GetItem(seq, i); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       if (item == NULL) { | 
					
						
							|  |  |  |         PyErr_Format(PyExc_TypeError, | 
					
						
							|  |  |  |                      "%s sequence type '%s' failed to retrieve index %d", | 
					
						
							|  |  |  |                      error_prefix, | 
					
						
							|  |  |  |                      Py_TYPE(seq)->tp_name, | 
					
						
							|  |  |  |                      i); | 
					
						
							|  |  |  |         ok = 0; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       else if ((item_seq_size = PySequence_Size(item)) == -1) { | 
					
						
							|  |  |  |         /* BLI_snprintf(error_str, error_str_size, "expected a sequence of %s", item_type_str); */ | 
					
						
							|  |  |  |         PyErr_Format(PyExc_TypeError, | 
					
						
							|  |  |  |                      "%s expected a sequence of %s, not %s", | 
					
						
							|  |  |  |                      error_prefix, | 
					
						
							|  |  |  |                      item_type_str, | 
					
						
							|  |  |  |                      Py_TYPE(item)->tp_name); | 
					
						
							|  |  |  |         ok = 0; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       /* arr[3][4][5]
 | 
					
						
							|  |  |  |        * dimsize[1] = 4 | 
					
						
							|  |  |  |        * dimsize[2] = 5 | 
					
						
							|  |  |  |        * | 
					
						
							|  |  |  |        * dim = 0 */ | 
					
						
							|  |  |  |       else if (item_seq_size != dimsize[dim + 1]) { | 
					
						
							|  |  |  |         /* BLI_snprintf(error_str, error_str_size,
 | 
					
						
							|  |  |  |          *              "sequences of dimension %d should contain %d items", | 
					
						
							|  |  |  |          *              dim + 1, dimsize[dim + 1]); */ | 
					
						
							|  |  |  |         PyErr_Format(PyExc_ValueError, | 
					
						
							|  |  |  |                      "%s sequences of dimension %d should contain %d items, not %d", | 
					
						
							|  |  |  |                      error_prefix, | 
					
						
							|  |  |  |                      dim + 1, | 
					
						
							|  |  |  |                      dimsize[dim + 1], | 
					
						
							|  |  |  |                      item_seq_size); | 
					
						
							|  |  |  |         ok = 0; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       else if (validate_array_type(item, | 
					
						
							|  |  |  |                                    dim + 1, | 
					
						
							|  |  |  |                                    totdim, | 
					
						
							|  |  |  |                                    dimsize, | 
					
						
							|  |  |  |                                    is_dynamic, | 
					
						
							|  |  |  |                                    check_item_type, | 
					
						
							|  |  |  |                                    item_type_str, | 
					
						
							|  |  |  |                                    error_prefix) == -1) { | 
					
						
							|  |  |  |         ok = 0; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       Py_XDECREF(item); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       if (!ok) { | 
					
						
							|  |  |  |         return -1; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   else { | 
					
						
							|  |  |  |     /* check that items are of correct type */ | 
					
						
							|  |  |  |     const int seq_size = PySequence_Size(seq); | 
					
						
							|  |  |  |     if (seq_size == -1) { | 
					
						
							|  |  |  |       PyErr_Format(PyExc_ValueError, | 
					
						
							|  |  |  |                    "%s sequence expected at dimension %d, not '%s'", | 
					
						
							|  |  |  |                    error_prefix, | 
					
						
							|  |  |  |                    dim + 1, | 
					
						
							|  |  |  |                    Py_TYPE(seq)->tp_name); | 
					
						
							|  |  |  |       return -1; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     else if ((seq_size != dimsize[dim]) && (is_dynamic == false)) { | 
					
						
							|  |  |  |       PyErr_Format(PyExc_ValueError, | 
					
						
							|  |  |  |                    "%s sequences of dimension %d should contain %d items, not %d", | 
					
						
							|  |  |  |                    error_prefix, | 
					
						
							|  |  |  |                    dim, | 
					
						
							|  |  |  |                    dimsize[dim], | 
					
						
							|  |  |  |                    seq_size); | 
					
						
							|  |  |  |       return -1; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     for (i = 0; i < seq_size; i++) { | 
					
						
							|  |  |  |       PyObject *item = PySequence_GetItem(seq, i); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       if (item == NULL) { | 
					
						
							|  |  |  |         PyErr_Format(PyExc_TypeError, | 
					
						
							|  |  |  |                      "%s sequence type '%s' failed to retrieve index %d", | 
					
						
							|  |  |  |                      error_prefix, | 
					
						
							|  |  |  |                      Py_TYPE(seq)->tp_name, | 
					
						
							|  |  |  |                      i); | 
					
						
							|  |  |  |         return -1; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       else if (!check_item_type(item)) { | 
					
						
							|  |  |  |         Py_DECREF(item); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-29 19:59:13 +10:00
										 |  |  | #if 0
 | 
					
						
							|  |  |  |         BLI_snprintf( | 
					
						
							|  |  |  |             error_str, error_str_size, "sequence items should be of type %s", item_type_str); | 
					
						
							|  |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |         PyErr_Format(PyExc_TypeError, | 
					
						
							|  |  |  |                      "%s expected sequence items of type %s, not %s", | 
					
						
							|  |  |  |                      error_prefix, | 
					
						
							|  |  |  |                      item_type_str, | 
					
						
							|  |  |  |                      Py_TYPE(item)->tp_name); | 
					
						
							|  |  |  |         return -1; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       Py_DECREF(item); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   return 0; /* ok */ | 
					
						
							| 
									
										
										
											
												Implemented dynamic and multidimensional array support in RNA.
Example code: http://www.pasteall.org/7332/c.
New API functions: http://www.pasteall.org/7330/c.
Maximum number of dimensions is currently limited to 3, but can be increased arbitrarily if needed.
What this means for ID property access:
* MeshFace.verts - dynamic array, size 3 or 4 depending on MFace.v4
* MeshTextureFace.uv - dynamic, 2-dimensional array, size depends on MFace.v4
* Object.matrix - 2-dimensional array
What this means for functions:
* more intuitive API possibility, for example:
  Mesh.add_vertices([(x, y, z), (x, y, z), ...])
  Mesh.add_faces([(1, 2, 3), (4, 5, 6), ...])
Python part is not complete yet, e.g. it is possible to:
MeshFace.verts = (1, 2, 3) # even if Mesh.verts is (1, 2, 3, 4) and vice-versa
MeshTextureFace.uv = [(0.0, 0.0)] * 4 # only if a corresponding MFace is a quad
but the following won't work:
MeshTextureFace.uv[3] = (0.0, 0.0) # setting uv[3] modifies MTFace.uv[1][0] instead of MTFace.uv[3]
											
										 
											2009-08-25 17:06:36 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* Returns the number of items in a single- or multi-dimensional sequence. */ | 
					
						
							| 
									
										
										
										
											2011-02-24 08:47:58 +00:00
										 |  |  | static int count_items(PyObject *seq, int dim) | 
					
						
							| 
									
										
										
											
												Implemented dynamic and multidimensional array support in RNA.
Example code: http://www.pasteall.org/7332/c.
New API functions: http://www.pasteall.org/7330/c.
Maximum number of dimensions is currently limited to 3, but can be increased arbitrarily if needed.
What this means for ID property access:
* MeshFace.verts - dynamic array, size 3 or 4 depending on MFace.v4
* MeshTextureFace.uv - dynamic, 2-dimensional array, size depends on MFace.v4
* Object.matrix - 2-dimensional array
What this means for functions:
* more intuitive API possibility, for example:
  Mesh.add_vertices([(x, y, z), (x, y, z), ...])
  Mesh.add_faces([(1, 2, 3), (4, 5, 6), ...])
Python part is not complete yet, e.g. it is possible to:
MeshFace.verts = (1, 2, 3) # even if Mesh.verts is (1, 2, 3, 4) and vice-versa
MeshTextureFace.uv = [(0.0, 0.0)] * 4 # only if a corresponding MFace is a quad
but the following won't work:
MeshTextureFace.uv[3] = (0.0, 0.0) # setting uv[3] modifies MTFace.uv[1][0] instead of MTFace.uv[3]
											
										 
											2009-08-25 17:06:36 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   int totitem = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (dim > 1) { | 
					
						
							|  |  |  |     const Py_ssize_t seq_size = PySequence_Size(seq); | 
					
						
							|  |  |  |     Py_ssize_t i; | 
					
						
							|  |  |  |     for (i = 0; i < seq_size; i++) { | 
					
						
							|  |  |  |       PyObject *item = PySequence_GetItem(seq, i); | 
					
						
							|  |  |  |       if (item) { | 
					
						
							|  |  |  |         const int tot = count_items(item, dim - 1); | 
					
						
							|  |  |  |         Py_DECREF(item); | 
					
						
							|  |  |  |         if (tot != -1) { | 
					
						
							|  |  |  |           totitem += tot; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         else { | 
					
						
							|  |  |  |           totitem = -1; | 
					
						
							|  |  |  |           break; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       else { | 
					
						
							|  |  |  |         totitem = -1; | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   else { | 
					
						
							|  |  |  |     totitem = PySequence_Size(seq); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   return totitem; | 
					
						
							| 
									
										
										
											
												Implemented dynamic and multidimensional array support in RNA.
Example code: http://www.pasteall.org/7332/c.
New API functions: http://www.pasteall.org/7330/c.
Maximum number of dimensions is currently limited to 3, but can be increased arbitrarily if needed.
What this means for ID property access:
* MeshFace.verts - dynamic array, size 3 or 4 depending on MFace.v4
* MeshTextureFace.uv - dynamic, 2-dimensional array, size depends on MFace.v4
* Object.matrix - 2-dimensional array
What this means for functions:
* more intuitive API possibility, for example:
  Mesh.add_vertices([(x, y, z), (x, y, z), ...])
  Mesh.add_faces([(1, 2, 3), (4, 5, 6), ...])
Python part is not complete yet, e.g. it is possible to:
MeshFace.verts = (1, 2, 3) # even if Mesh.verts is (1, 2, 3, 4) and vice-versa
MeshTextureFace.uv = [(0.0, 0.0)] * 4 # only if a corresponding MFace is a quad
but the following won't work:
MeshTextureFace.uv[3] = (0.0, 0.0) # setting uv[3] modifies MTFace.uv[1][0] instead of MTFace.uv[3]
											
										 
											2009-08-25 17:06:36 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-09-06 15:13:57 +00:00
										 |  |  | /* Modifies property array length if needed and PROP_DYNAMIC flag is set. */ | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | static int validate_array_length(PyObject *rvalue, | 
					
						
							|  |  |  |                                  PointerRNA *ptr, | 
					
						
							|  |  |  |                                  PropertyRNA *prop, | 
					
						
							|  |  |  |                                  int lvalue_dim, | 
					
						
							| 
									
										
										
										
											2020-03-25 17:58:58 +11:00
										 |  |  |                                  int *r_totitem, | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |                                  const char *error_prefix) | 
					
						
							| 
									
										
										
											
												Implemented dynamic and multidimensional array support in RNA.
Example code: http://www.pasteall.org/7332/c.
New API functions: http://www.pasteall.org/7330/c.
Maximum number of dimensions is currently limited to 3, but can be increased arbitrarily if needed.
What this means for ID property access:
* MeshFace.verts - dynamic array, size 3 or 4 depending on MFace.v4
* MeshTextureFace.uv - dynamic, 2-dimensional array, size depends on MFace.v4
* Object.matrix - 2-dimensional array
What this means for functions:
* more intuitive API possibility, for example:
  Mesh.add_vertices([(x, y, z), (x, y, z), ...])
  Mesh.add_faces([(1, 2, 3), (4, 5, 6), ...])
Python part is not complete yet, e.g. it is possible to:
MeshFace.verts = (1, 2, 3) # even if Mesh.verts is (1, 2, 3, 4) and vice-versa
MeshTextureFace.uv = [(0.0, 0.0)] * 4 # only if a corresponding MFace is a quad
but the following won't work:
MeshTextureFace.uv[3] = (0.0, 0.0) # setting uv[3] modifies MTFace.uv[1][0] instead of MTFace.uv[3]
											
										 
											2009-08-25 17:06:36 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   int dimsize[MAX_ARRAY_DIMENSION]; | 
					
						
							|  |  |  |   int tot, totdim, len; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   totdim = RNA_property_array_dimension(ptr, prop, dimsize); | 
					
						
							|  |  |  |   tot = count_items(rvalue, totdim - lvalue_dim); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (tot == -1) { | 
					
						
							|  |  |  |     PyErr_Format(PyExc_ValueError, | 
					
						
							|  |  |  |                  "%s %.200s.%.200s, error validating the sequence length", | 
					
						
							|  |  |  |                  error_prefix, | 
					
						
							|  |  |  |                  RNA_struct_identifier(ptr->type), | 
					
						
							|  |  |  |                  RNA_property_identifier(prop)); | 
					
						
							|  |  |  |     return -1; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   else if ((RNA_property_flag(prop) & PROP_DYNAMIC) && lvalue_dim == 0) { | 
					
						
							|  |  |  |     if (RNA_property_array_length(ptr, prop) != tot) { | 
					
						
							| 
									
										
										
										
											2009-09-09 19:40:46 +00:00
										 |  |  | #if 0
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |       /* length is flexible */ | 
					
						
							|  |  |  |       if (!RNA_property_dynamic_array_set_length(ptr, prop, tot)) { | 
					
						
							|  |  |  |         /* BLI_snprintf(error_str, error_str_size,
 | 
					
						
							|  |  |  |          *              "%s.%s: array length cannot be changed to %d", | 
					
						
							|  |  |  |          *              RNA_struct_identifier(ptr->type), RNA_property_identifier(prop), tot); */ | 
					
						
							| 
									
										
										
										
											2019-04-17 08:24:14 +02:00
										 |  |  |         PyErr_Format(PyExc_ValueError, | 
					
						
							|  |  |  |                      "%s %s.%s: array length cannot be changed to %d", | 
					
						
							|  |  |  |                      error_prefix, | 
					
						
							|  |  |  |                      RNA_struct_identifier(ptr->type), | 
					
						
							|  |  |  |                      RNA_property_identifier(prop), | 
					
						
							|  |  |  |                      tot); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |         return -1; | 
					
						
							|  |  |  |       } | 
					
						
							| 
									
										
										
										
											2009-09-09 19:40:46 +00:00
										 |  |  | #else
 | 
					
						
							| 
									
										
										
										
											2020-03-25 17:58:58 +11:00
										 |  |  |       *r_totitem = tot; | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |       return 0; | 
					
						
							| 
									
										
										
										
											2010-08-31 11:31:21 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-09-09 19:40:46 +00:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     len = tot; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   else { | 
					
						
							|  |  |  |     /* length is a constraint */ | 
					
						
							|  |  |  |     if (!lvalue_dim) { | 
					
						
							|  |  |  |       len = RNA_property_array_length(ptr, prop); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     /* array item assignment */ | 
					
						
							|  |  |  |     else { | 
					
						
							|  |  |  |       int i; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       len = 1; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       /* arr[3][4][5]
 | 
					
						
							|  |  |  |        * | 
					
						
							|  |  |  |        *    arr[2] = x | 
					
						
							|  |  |  |        *    dimsize = {4, 5} | 
					
						
							|  |  |  |        *    dimsize[1] = 4 | 
					
						
							|  |  |  |        *    dimsize[2] = 5 | 
					
						
							|  |  |  |        *    lvalue_dim = 0, totdim = 3 | 
					
						
							|  |  |  |        * | 
					
						
							|  |  |  |        *    arr[2][3] = x | 
					
						
							|  |  |  |        *    lvalue_dim = 1 | 
					
						
							|  |  |  |        * | 
					
						
							|  |  |  |        *    arr[2][3][4] = x | 
					
						
							|  |  |  |        *    lvalue_dim = 2 */ | 
					
						
							|  |  |  |       for (i = lvalue_dim; i < totdim; i++) { | 
					
						
							|  |  |  |         len *= dimsize[i]; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (tot != len) { | 
					
						
							|  |  |  |       /* BLI_snprintf(error_str, error_str_size, "sequence must have length of %d", len); */ | 
					
						
							|  |  |  |       PyErr_Format(PyExc_ValueError, | 
					
						
							|  |  |  |                    "%s %.200s.%.200s, sequence must have %d items total, not %d", | 
					
						
							|  |  |  |                    error_prefix, | 
					
						
							|  |  |  |                    RNA_struct_identifier(ptr->type), | 
					
						
							|  |  |  |                    RNA_property_identifier(prop), | 
					
						
							|  |  |  |                    len, | 
					
						
							|  |  |  |                    tot); | 
					
						
							|  |  |  |       return -1; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-03-25 17:58:58 +11:00
										 |  |  |   *r_totitem = len; | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |   return 0; | 
					
						
							| 
									
										
										
											
												Implemented dynamic and multidimensional array support in RNA.
Example code: http://www.pasteall.org/7332/c.
New API functions: http://www.pasteall.org/7330/c.
Maximum number of dimensions is currently limited to 3, but can be increased arbitrarily if needed.
What this means for ID property access:
* MeshFace.verts - dynamic array, size 3 or 4 depending on MFace.v4
* MeshTextureFace.uv - dynamic, 2-dimensional array, size depends on MFace.v4
* Object.matrix - 2-dimensional array
What this means for functions:
* more intuitive API possibility, for example:
  Mesh.add_vertices([(x, y, z), (x, y, z), ...])
  Mesh.add_faces([(1, 2, 3), (4, 5, 6), ...])
Python part is not complete yet, e.g. it is possible to:
MeshFace.verts = (1, 2, 3) # even if Mesh.verts is (1, 2, 3, 4) and vice-versa
MeshTextureFace.uv = [(0.0, 0.0)] * 4 # only if a corresponding MFace is a quad
but the following won't work:
MeshTextureFace.uv[3] = (0.0, 0.0) # setting uv[3] modifies MTFace.uv[1][0] instead of MTFace.uv[3]
											
										 
											2009-08-25 17:06:36 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | static int validate_array(PyObject *rvalue, | 
					
						
							|  |  |  |                           PointerRNA *ptr, | 
					
						
							|  |  |  |                           PropertyRNA *prop, | 
					
						
							|  |  |  |                           int lvalue_dim, | 
					
						
							|  |  |  |                           ItemTypeCheckFunc check_item_type, | 
					
						
							|  |  |  |                           const char *item_type_str, | 
					
						
							| 
									
										
										
										
											2020-03-25 17:58:58 +11:00
										 |  |  |                           int *r_totitem, | 
					
						
							| 
									
										
										
										
											2011-11-26 15:18:30 +00:00
										 |  |  |                           const char *error_prefix) | 
					
						
							| 
									
										
										
										
											2009-09-06 15:13:57 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   int dimsize[MAX_ARRAY_DIMENSION]; | 
					
						
							|  |  |  |   int totdim = RNA_property_array_dimension(ptr, prop, dimsize); | 
					
						
							| 
									
										
										
										
											2009-09-06 15:13:57 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   /* validate type first because length validation may modify property array length */ | 
					
						
							| 
									
										
										
										
											2009-09-06 15:13:57 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-12-22 08:44:08 +00:00
										 |  |  | #ifdef USE_MATHUTILS
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   if (lvalue_dim == 0) { /* only valid for first level array */ | 
					
						
							|  |  |  |     if (MatrixObject_Check(rvalue)) { | 
					
						
							|  |  |  |       MatrixObject *pymat = (MatrixObject *)rvalue; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       if (BaseMath_ReadCallback(pymat) == -1) { | 
					
						
							|  |  |  |         return -1; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       if (RNA_property_type(prop) != PROP_FLOAT) { | 
					
						
							|  |  |  |         PyErr_Format(PyExc_ValueError, | 
					
						
							|  |  |  |                      "%s %.200s.%.200s, matrix assign to non float array", | 
					
						
							|  |  |  |                      error_prefix, | 
					
						
							|  |  |  |                      RNA_struct_identifier(ptr->type), | 
					
						
							|  |  |  |                      RNA_property_identifier(prop)); | 
					
						
							|  |  |  |         return -1; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       else if (totdim != 2) { | 
					
						
							|  |  |  |         PyErr_Format(PyExc_ValueError, | 
					
						
							|  |  |  |                      "%s %.200s.%.200s, matrix assign array with %d dimensions", | 
					
						
							|  |  |  |                      error_prefix, | 
					
						
							|  |  |  |                      RNA_struct_identifier(ptr->type), | 
					
						
							|  |  |  |                      RNA_property_identifier(prop), | 
					
						
							|  |  |  |                      totdim); | 
					
						
							|  |  |  |         return -1; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       else if (pymat->num_col != dimsize[0] || pymat->num_row != dimsize[1]) { | 
					
						
							|  |  |  |         PyErr_Format(PyExc_ValueError, | 
					
						
							|  |  |  |                      "%s %.200s.%.200s, matrix assign dimension size mismatch, " | 
					
						
							|  |  |  |                      "is %dx%d, expected be %dx%d", | 
					
						
							|  |  |  |                      error_prefix, | 
					
						
							|  |  |  |                      RNA_struct_identifier(ptr->type), | 
					
						
							|  |  |  |                      RNA_property_identifier(prop), | 
					
						
							|  |  |  |                      pymat->num_col, | 
					
						
							|  |  |  |                      pymat->num_row, | 
					
						
							|  |  |  |                      dimsize[0], | 
					
						
							|  |  |  |                      dimsize[1]); | 
					
						
							|  |  |  |         return -1; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       else { | 
					
						
							| 
									
										
										
										
											2020-03-25 17:58:58 +11:00
										 |  |  |         *r_totitem = dimsize[0] * dimsize[1]; | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |         return 0; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2011-12-22 08:44:08 +00:00
										 |  |  | #endif /* USE_MATHUTILS */
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   { | 
					
						
							|  |  |  |     const int prop_flag = RNA_property_flag(prop); | 
					
						
							|  |  |  |     if (validate_array_type(rvalue, | 
					
						
							|  |  |  |                             lvalue_dim, | 
					
						
							|  |  |  |                             totdim, | 
					
						
							|  |  |  |                             dimsize, | 
					
						
							|  |  |  |                             (prop_flag & PROP_DYNAMIC) != 0, | 
					
						
							|  |  |  |                             check_item_type, | 
					
						
							|  |  |  |                             item_type_str, | 
					
						
							|  |  |  |                             error_prefix) == -1) { | 
					
						
							|  |  |  |       return -1; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-03-25 17:58:58 +11:00
										 |  |  |     return validate_array_length(rvalue, ptr, prop, lvalue_dim, r_totitem, error_prefix); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2009-09-06 15:13:57 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | static char *copy_value_single(PyObject *item, | 
					
						
							|  |  |  |                                PointerRNA *ptr, | 
					
						
							|  |  |  |                                PropertyRNA *prop, | 
					
						
							|  |  |  |                                char *data, | 
					
						
							| 
									
										
										
										
											2020-02-20 15:38:58 +11:00
										 |  |  |                                uint item_size, | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |                                int *index, | 
					
						
							|  |  |  |                                const ItemConvert_FuncArg *convert_item, | 
					
						
							|  |  |  |                                RNA_SetIndexFunc rna_set_index) | 
					
						
							| 
									
										
										
										
											2011-01-13 16:00:14 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   if (!data) { | 
					
						
							|  |  |  |     union { | 
					
						
							|  |  |  |       float fl; | 
					
						
							|  |  |  |       int i; | 
					
						
							|  |  |  |     } value_buf; | 
					
						
							|  |  |  |     char *value = (void *)&value_buf; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     convert_item->func(&convert_item->arg, item, value); | 
					
						
							|  |  |  |     rna_set_index(ptr, prop, *index, value); | 
					
						
							|  |  |  |     (*index) += 1; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   else { | 
					
						
							|  |  |  |     convert_item->func(&convert_item->arg, item, data); | 
					
						
							|  |  |  |     data += item_size; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   return data; | 
					
						
							| 
									
										
										
										
											2011-01-13 16:00:14 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | static char *copy_values(PyObject *seq, | 
					
						
							|  |  |  |                          PointerRNA *ptr, | 
					
						
							|  |  |  |                          PropertyRNA *prop, | 
					
						
							|  |  |  |                          int dim, | 
					
						
							|  |  |  |                          char *data, | 
					
						
							| 
									
										
										
										
											2020-02-20 15:38:58 +11:00
										 |  |  |                          uint item_size, | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |                          int *index, | 
					
						
							|  |  |  |                          const ItemConvert_FuncArg *convert_item, | 
					
						
							|  |  |  |                          RNA_SetIndexFunc rna_set_index) | 
					
						
							| 
									
										
										
											
												Implemented dynamic and multidimensional array support in RNA.
Example code: http://www.pasteall.org/7332/c.
New API functions: http://www.pasteall.org/7330/c.
Maximum number of dimensions is currently limited to 3, but can be increased arbitrarily if needed.
What this means for ID property access:
* MeshFace.verts - dynamic array, size 3 or 4 depending on MFace.v4
* MeshTextureFace.uv - dynamic, 2-dimensional array, size depends on MFace.v4
* Object.matrix - 2-dimensional array
What this means for functions:
* more intuitive API possibility, for example:
  Mesh.add_vertices([(x, y, z), (x, y, z), ...])
  Mesh.add_faces([(1, 2, 3), (4, 5, 6), ...])
Python part is not complete yet, e.g. it is possible to:
MeshFace.verts = (1, 2, 3) # even if Mesh.verts is (1, 2, 3, 4) and vice-versa
MeshTextureFace.uv = [(0.0, 0.0)] * 4 # only if a corresponding MFace is a quad
but the following won't work:
MeshTextureFace.uv[3] = (0.0, 0.0) # setting uv[3] modifies MTFace.uv[1][0] instead of MTFace.uv[3]
											
										 
											2009-08-25 17:06:36 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   int totdim = RNA_property_array_dimension(ptr, prop, NULL); | 
					
						
							|  |  |  |   const Py_ssize_t seq_size = PySequence_Size(seq); | 
					
						
							|  |  |  |   Py_ssize_t i; | 
					
						
							| 
									
										
										
										
											2011-08-09 20:00:53 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   /* Regarding PySequence_GetItem() failing.
 | 
					
						
							|  |  |  |    * | 
					
						
							|  |  |  |    * This should never be NULL since we validated it, _but_ some tricky python | 
					
						
							|  |  |  |    * developer could write their own sequence type which succeeds on | 
					
						
							|  |  |  |    * validating but fails later somehow, so include checks for safety. | 
					
						
							|  |  |  |    */ | 
					
						
							| 
									
										
										
										
											2011-02-27 08:31:10 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   /* Note that 'data can be NULL' */ | 
					
						
							| 
									
										
										
										
											2011-06-17 02:22:38 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   if (seq_size == -1) { | 
					
						
							|  |  |  |     return NULL; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2011-12-22 08:44:08 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | #ifdef USE_MATHUTILS
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   if (dim == 0) { | 
					
						
							|  |  |  |     if (MatrixObject_Check(seq)) { | 
					
						
							|  |  |  |       MatrixObject *pymat = (MatrixObject *)seq; | 
					
						
							|  |  |  |       size_t allocsize = pymat->num_col * pymat->num_row * sizeof(float); | 
					
						
							| 
									
										
										
										
											2011-12-22 08:44:08 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |       /* read callback already done by validate */ | 
					
						
							|  |  |  |       /* since this is the first iteration we can assume data is allocated */ | 
					
						
							|  |  |  |       memcpy(data, pymat->matrix, allocsize); | 
					
						
							| 
									
										
										
										
											2011-12-22 08:44:08 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |       /* not really needed but do for completeness */ | 
					
						
							|  |  |  |       data += allocsize; | 
					
						
							| 
									
										
										
										
											2011-12-22 08:44:08 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |       return data; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2011-12-22 08:44:08 +00:00
										 |  |  | #endif /* USE_MATHUTILS */
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   for (i = 0; i < seq_size; i++) { | 
					
						
							|  |  |  |     PyObject *item = PySequence_GetItem(seq, i); | 
					
						
							|  |  |  |     if (item) { | 
					
						
							|  |  |  |       if (dim + 1 < totdim) { | 
					
						
							|  |  |  |         data = copy_values( | 
					
						
							|  |  |  |             item, ptr, prop, dim + 1, data, item_size, index, convert_item, rna_set_index); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       else { | 
					
						
							|  |  |  |         data = copy_value_single( | 
					
						
							|  |  |  |             item, ptr, prop, data, item_size, index, convert_item, rna_set_index); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       Py_DECREF(item); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       /* data may be NULL, but the for loop checks */ | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     else { | 
					
						
							|  |  |  |       return NULL; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   return data; | 
					
						
							| 
									
										
										
											
												Implemented dynamic and multidimensional array support in RNA.
Example code: http://www.pasteall.org/7332/c.
New API functions: http://www.pasteall.org/7330/c.
Maximum number of dimensions is currently limited to 3, but can be increased arbitrarily if needed.
What this means for ID property access:
* MeshFace.verts - dynamic array, size 3 or 4 depending on MFace.v4
* MeshTextureFace.uv - dynamic, 2-dimensional array, size depends on MFace.v4
* Object.matrix - 2-dimensional array
What this means for functions:
* more intuitive API possibility, for example:
  Mesh.add_vertices([(x, y, z), (x, y, z), ...])
  Mesh.add_faces([(1, 2, 3), (4, 5, 6), ...])
Python part is not complete yet, e.g. it is possible to:
MeshFace.verts = (1, 2, 3) # even if Mesh.verts is (1, 2, 3, 4) and vice-versa
MeshTextureFace.uv = [(0.0, 0.0)] * 4 # only if a corresponding MFace is a quad
but the following won't work:
MeshTextureFace.uv[3] = (0.0, 0.0) # setting uv[3] modifies MTFace.uv[1][0] instead of MTFace.uv[3]
											
										 
											2009-08-25 17:06:36 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | static int py_to_array(PyObject *seq, | 
					
						
							|  |  |  |                        PointerRNA *ptr, | 
					
						
							|  |  |  |                        PropertyRNA *prop, | 
					
						
							|  |  |  |                        char *param_data, | 
					
						
							|  |  |  |                        ItemTypeCheckFunc check_item_type, | 
					
						
							|  |  |  |                        const char *item_type_str, | 
					
						
							|  |  |  |                        int item_size, | 
					
						
							|  |  |  |                        const ItemConvert_FuncArg *convert_item, | 
					
						
							|  |  |  |                        RNA_SetArrayFunc rna_set_array, | 
					
						
							|  |  |  |                        const char *error_prefix) | 
					
						
							| 
									
										
										
											
												Implemented dynamic and multidimensional array support in RNA.
Example code: http://www.pasteall.org/7332/c.
New API functions: http://www.pasteall.org/7330/c.
Maximum number of dimensions is currently limited to 3, but can be increased arbitrarily if needed.
What this means for ID property access:
* MeshFace.verts - dynamic array, size 3 or 4 depending on MFace.v4
* MeshTextureFace.uv - dynamic, 2-dimensional array, size depends on MFace.v4
* Object.matrix - 2-dimensional array
What this means for functions:
* more intuitive API possibility, for example:
  Mesh.add_vertices([(x, y, z), (x, y, z), ...])
  Mesh.add_faces([(1, 2, 3), (4, 5, 6), ...])
Python part is not complete yet, e.g. it is possible to:
MeshFace.verts = (1, 2, 3) # even if Mesh.verts is (1, 2, 3, 4) and vice-versa
MeshTextureFace.uv = [(0.0, 0.0)] * 4 # only if a corresponding MFace is a quad
but the following won't work:
MeshTextureFace.uv[3] = (0.0, 0.0) # setting uv[3] modifies MTFace.uv[1][0] instead of MTFace.uv[3]
											
										 
											2009-08-25 17:06:36 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   /*int totdim, dim_size[MAX_ARRAY_DIMENSION];*/ | 
					
						
							|  |  |  |   int totitem; | 
					
						
							|  |  |  |   char *data = NULL; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   /*totdim = RNA_property_array_dimension(ptr, prop, dim_size);*/ /*UNUSED*/ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (validate_array(seq, ptr, prop, 0, check_item_type, item_type_str, &totitem, error_prefix) == | 
					
						
							|  |  |  |       -1) { | 
					
						
							|  |  |  |     return -1; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (totitem) { | 
					
						
							|  |  |  |     /* note: this code is confusing */ | 
					
						
							|  |  |  |     if (param_data && RNA_property_flag(prop) & PROP_DYNAMIC) { | 
					
						
							|  |  |  |       /* not freeing allocated mem, RNA_parameter_list_free() will do this */ | 
					
						
							|  |  |  |       ParameterDynAlloc *param_alloc = (ParameterDynAlloc *)param_data; | 
					
						
							|  |  |  |       param_alloc->array_tot = (int)totitem; | 
					
						
							| 
									
										
										
										
											2019-08-14 23:29:46 +10:00
										 |  |  | 
 | 
					
						
							|  |  |  |       /* freeing param list will free */ | 
					
						
							|  |  |  |       param_alloc->array = MEM_callocN(item_size * totitem, "py_to_array dyn"); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |       data = param_alloc->array; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     else if (param_data) { | 
					
						
							|  |  |  |       data = param_data; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     else { | 
					
						
							|  |  |  |       data = PyMem_MALLOC(item_size * totitem); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /* will only fail in very rare cases since we already validated the
 | 
					
						
							|  |  |  |      * python data, the check here is mainly for completeness. */ | 
					
						
							|  |  |  |     if (copy_values(seq, ptr, prop, 0, data, item_size, NULL, convert_item, NULL) != NULL) { | 
					
						
							|  |  |  |       if (param_data == NULL) { | 
					
						
							|  |  |  |         /* NULL can only pass through in case RNA property arraylength is 0 (impossible?) */ | 
					
						
							|  |  |  |         rna_set_array(ptr, prop, data); | 
					
						
							|  |  |  |         PyMem_FREE(data); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     else { | 
					
						
							|  |  |  |       if (param_data == NULL) { | 
					
						
							|  |  |  |         PyMem_FREE(data); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       PyErr_Format(PyExc_TypeError, | 
					
						
							|  |  |  |                    "%s internal error parsing sequence of type '%s' after successful validation", | 
					
						
							|  |  |  |                    error_prefix, | 
					
						
							|  |  |  |                    Py_TYPE(seq)->tp_name); | 
					
						
							|  |  |  |       return -1; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   return 0; | 
					
						
							| 
									
										
										
											
												Implemented dynamic and multidimensional array support in RNA.
Example code: http://www.pasteall.org/7332/c.
New API functions: http://www.pasteall.org/7330/c.
Maximum number of dimensions is currently limited to 3, but can be increased arbitrarily if needed.
What this means for ID property access:
* MeshFace.verts - dynamic array, size 3 or 4 depending on MFace.v4
* MeshTextureFace.uv - dynamic, 2-dimensional array, size depends on MFace.v4
* Object.matrix - 2-dimensional array
What this means for functions:
* more intuitive API possibility, for example:
  Mesh.add_vertices([(x, y, z), (x, y, z), ...])
  Mesh.add_faces([(1, 2, 3), (4, 5, 6), ...])
Python part is not complete yet, e.g. it is possible to:
MeshFace.verts = (1, 2, 3) # even if Mesh.verts is (1, 2, 3, 4) and vice-versa
MeshTextureFace.uv = [(0.0, 0.0)] * 4 # only if a corresponding MFace is a quad
but the following won't work:
MeshTextureFace.uv[3] = (0.0, 0.0) # setting uv[3] modifies MTFace.uv[1][0] instead of MTFace.uv[3]
											
										 
											2009-08-25 17:06:36 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | static int py_to_array_index(PyObject *py, | 
					
						
							|  |  |  |                              PointerRNA *ptr, | 
					
						
							|  |  |  |                              PropertyRNA *prop, | 
					
						
							|  |  |  |                              int lvalue_dim, | 
					
						
							|  |  |  |                              int arrayoffset, | 
					
						
							|  |  |  |                              int index, | 
					
						
							|  |  |  |                              ItemTypeCheckFunc check_item_type, | 
					
						
							|  |  |  |                              const char *item_type_str, | 
					
						
							|  |  |  |                              const ItemConvert_FuncArg *convert_item, | 
					
						
							|  |  |  |                              RNA_SetIndexFunc rna_set_index, | 
					
						
							|  |  |  |                              const char *error_prefix) | 
					
						
							| 
									
										
										
										
											2009-09-06 15:13:57 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   int totdim, dimsize[MAX_ARRAY_DIMENSION]; | 
					
						
							|  |  |  |   int totitem, i; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   totdim = RNA_property_array_dimension(ptr, prop, dimsize); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   /* convert index */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   /* arr[3][4][5]
 | 
					
						
							|  |  |  |    * | 
					
						
							|  |  |  |    *    arr[2] = x | 
					
						
							|  |  |  |    *    lvalue_dim = 0, index = 0 + 2 * 4 * 5 | 
					
						
							|  |  |  |    * | 
					
						
							|  |  |  |    *    arr[2][3] = x | 
					
						
							|  |  |  |    *    lvalue_dim = 1, index = 40 + 3 * 5 */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   lvalue_dim++; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   for (i = lvalue_dim; i < totdim; i++) { | 
					
						
							|  |  |  |     index *= dimsize[i]; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   index += arrayoffset; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (lvalue_dim == totdim) { /* single item, assign directly */ | 
					
						
							|  |  |  |     if (!check_item_type(py)) { | 
					
						
							|  |  |  |       PyErr_Format(PyExc_TypeError, | 
					
						
							|  |  |  |                    "%s %.200s.%.200s, expected a %s type, not %s", | 
					
						
							|  |  |  |                    error_prefix, | 
					
						
							|  |  |  |                    RNA_struct_identifier(ptr->type), | 
					
						
							|  |  |  |                    RNA_property_identifier(prop), | 
					
						
							|  |  |  |                    item_type_str, | 
					
						
							|  |  |  |                    Py_TYPE(py)->tp_name); | 
					
						
							|  |  |  |       return -1; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     copy_value_single(py, ptr, prop, NULL, 0, &index, convert_item, rna_set_index); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   else { | 
					
						
							|  |  |  |     if (validate_array( | 
					
						
							|  |  |  |             py, ptr, prop, lvalue_dim, check_item_type, item_type_str, &totitem, error_prefix) == | 
					
						
							|  |  |  |         -1) { | 
					
						
							|  |  |  |       return -1; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (totitem) { | 
					
						
							|  |  |  |       copy_values(py, ptr, prop, lvalue_dim, NULL, 0, &index, convert_item, rna_set_index); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   return 0; | 
					
						
							| 
									
										
										
										
											2009-09-06 15:13:57 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-03-08 15:33:28 +11:00
										 |  |  | static void py_to_float(const struct ItemConvertArgData *arg, PyObject *py, char *data) | 
					
						
							| 
									
										
										
											
												Implemented dynamic and multidimensional array support in RNA.
Example code: http://www.pasteall.org/7332/c.
New API functions: http://www.pasteall.org/7330/c.
Maximum number of dimensions is currently limited to 3, but can be increased arbitrarily if needed.
What this means for ID property access:
* MeshFace.verts - dynamic array, size 3 or 4 depending on MFace.v4
* MeshTextureFace.uv - dynamic, 2-dimensional array, size depends on MFace.v4
* Object.matrix - 2-dimensional array
What this means for functions:
* more intuitive API possibility, for example:
  Mesh.add_vertices([(x, y, z), (x, y, z), ...])
  Mesh.add_faces([(1, 2, 3), (4, 5, 6), ...])
Python part is not complete yet, e.g. it is possible to:
MeshFace.verts = (1, 2, 3) # even if Mesh.verts is (1, 2, 3, 4) and vice-versa
MeshTextureFace.uv = [(0.0, 0.0)] * 4 # only if a corresponding MFace is a quad
but the following won't work:
MeshTextureFace.uv[3] = (0.0, 0.0) # setting uv[3] modifies MTFace.uv[1][0] instead of MTFace.uv[3]
											
										 
											2009-08-25 17:06:36 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   const float *range = arg->float_data.range; | 
					
						
							|  |  |  |   float value = (float)PyFloat_AsDouble(py); | 
					
						
							|  |  |  |   CLAMP(value, range[0], range[1]); | 
					
						
							|  |  |  |   *(float *)data = value; | 
					
						
							| 
									
										
										
											
												Implemented dynamic and multidimensional array support in RNA.
Example code: http://www.pasteall.org/7332/c.
New API functions: http://www.pasteall.org/7330/c.
Maximum number of dimensions is currently limited to 3, but can be increased arbitrarily if needed.
What this means for ID property access:
* MeshFace.verts - dynamic array, size 3 or 4 depending on MFace.v4
* MeshTextureFace.uv - dynamic, 2-dimensional array, size depends on MFace.v4
* Object.matrix - 2-dimensional array
What this means for functions:
* more intuitive API possibility, for example:
  Mesh.add_vertices([(x, y, z), (x, y, z), ...])
  Mesh.add_faces([(1, 2, 3), (4, 5, 6), ...])
Python part is not complete yet, e.g. it is possible to:
MeshFace.verts = (1, 2, 3) # even if Mesh.verts is (1, 2, 3, 4) and vice-versa
MeshTextureFace.uv = [(0.0, 0.0)] * 4 # only if a corresponding MFace is a quad
but the following won't work:
MeshTextureFace.uv[3] = (0.0, 0.0) # setting uv[3] modifies MTFace.uv[1][0] instead of MTFace.uv[3]
											
										 
											2009-08-25 17:06:36 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-03-08 15:33:28 +11:00
										 |  |  | static void py_to_int(const struct ItemConvertArgData *arg, PyObject *py, char *data) | 
					
						
							| 
									
										
										
											
												Implemented dynamic and multidimensional array support in RNA.
Example code: http://www.pasteall.org/7332/c.
New API functions: http://www.pasteall.org/7330/c.
Maximum number of dimensions is currently limited to 3, but can be increased arbitrarily if needed.
What this means for ID property access:
* MeshFace.verts - dynamic array, size 3 or 4 depending on MFace.v4
* MeshTextureFace.uv - dynamic, 2-dimensional array, size depends on MFace.v4
* Object.matrix - 2-dimensional array
What this means for functions:
* more intuitive API possibility, for example:
  Mesh.add_vertices([(x, y, z), (x, y, z), ...])
  Mesh.add_faces([(1, 2, 3), (4, 5, 6), ...])
Python part is not complete yet, e.g. it is possible to:
MeshFace.verts = (1, 2, 3) # even if Mesh.verts is (1, 2, 3, 4) and vice-versa
MeshTextureFace.uv = [(0.0, 0.0)] * 4 # only if a corresponding MFace is a quad
but the following won't work:
MeshTextureFace.uv[3] = (0.0, 0.0) # setting uv[3] modifies MTFace.uv[1][0] instead of MTFace.uv[3]
											
										 
											2009-08-25 17:06:36 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   const int *range = arg->int_data.range; | 
					
						
							|  |  |  |   int value = PyC_Long_AsI32(py); | 
					
						
							|  |  |  |   CLAMP(value, range[0], range[1]); | 
					
						
							|  |  |  |   *(int *)data = value; | 
					
						
							| 
									
										
										
											
												Implemented dynamic and multidimensional array support in RNA.
Example code: http://www.pasteall.org/7332/c.
New API functions: http://www.pasteall.org/7330/c.
Maximum number of dimensions is currently limited to 3, but can be increased arbitrarily if needed.
What this means for ID property access:
* MeshFace.verts - dynamic array, size 3 or 4 depending on MFace.v4
* MeshTextureFace.uv - dynamic, 2-dimensional array, size depends on MFace.v4
* Object.matrix - 2-dimensional array
What this means for functions:
* more intuitive API possibility, for example:
  Mesh.add_vertices([(x, y, z), (x, y, z), ...])
  Mesh.add_faces([(1, 2, 3), (4, 5, 6), ...])
Python part is not complete yet, e.g. it is possible to:
MeshFace.verts = (1, 2, 3) # even if Mesh.verts is (1, 2, 3, 4) and vice-versa
MeshTextureFace.uv = [(0.0, 0.0)] * 4 # only if a corresponding MFace is a quad
but the following won't work:
MeshTextureFace.uv[3] = (0.0, 0.0) # setting uv[3] modifies MTFace.uv[1][0] instead of MTFace.uv[3]
											
										 
											2009-08-25 17:06:36 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-03-08 15:33:28 +11:00
										 |  |  | static void py_to_bool(const struct ItemConvertArgData *UNUSED(arg), PyObject *py, char *data) | 
					
						
							| 
									
										
										
											
												Implemented dynamic and multidimensional array support in RNA.
Example code: http://www.pasteall.org/7332/c.
New API functions: http://www.pasteall.org/7330/c.
Maximum number of dimensions is currently limited to 3, but can be increased arbitrarily if needed.
What this means for ID property access:
* MeshFace.verts - dynamic array, size 3 or 4 depending on MFace.v4
* MeshTextureFace.uv - dynamic, 2-dimensional array, size depends on MFace.v4
* Object.matrix - 2-dimensional array
What this means for functions:
* more intuitive API possibility, for example:
  Mesh.add_vertices([(x, y, z), (x, y, z), ...])
  Mesh.add_faces([(1, 2, 3), (4, 5, 6), ...])
Python part is not complete yet, e.g. it is possible to:
MeshFace.verts = (1, 2, 3) # even if Mesh.verts is (1, 2, 3, 4) and vice-versa
MeshTextureFace.uv = [(0.0, 0.0)] * 4 # only if a corresponding MFace is a quad
but the following won't work:
MeshTextureFace.uv[3] = (0.0, 0.0) # setting uv[3] modifies MTFace.uv[1][0] instead of MTFace.uv[3]
											
										 
											2009-08-25 17:06:36 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   *(bool *)data = (bool)PyObject_IsTrue(py); | 
					
						
							| 
									
										
										
											
												Implemented dynamic and multidimensional array support in RNA.
Example code: http://www.pasteall.org/7332/c.
New API functions: http://www.pasteall.org/7330/c.
Maximum number of dimensions is currently limited to 3, but can be increased arbitrarily if needed.
What this means for ID property access:
* MeshFace.verts - dynamic array, size 3 or 4 depending on MFace.v4
* MeshTextureFace.uv - dynamic, 2-dimensional array, size depends on MFace.v4
* Object.matrix - 2-dimensional array
What this means for functions:
* more intuitive API possibility, for example:
  Mesh.add_vertices([(x, y, z), (x, y, z), ...])
  Mesh.add_faces([(1, 2, 3), (4, 5, 6), ...])
Python part is not complete yet, e.g. it is possible to:
MeshFace.verts = (1, 2, 3) # even if Mesh.verts is (1, 2, 3, 4) and vice-versa
MeshTextureFace.uv = [(0.0, 0.0)] * 4 # only if a corresponding MFace is a quad
but the following won't work:
MeshTextureFace.uv[3] = (0.0, 0.0) # setting uv[3] modifies MTFace.uv[1][0] instead of MTFace.uv[3]
											
										 
											2009-08-25 17:06:36 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static int py_float_check(PyObject *py) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   /* accept both floats and integers */ | 
					
						
							|  |  |  |   return PyNumber_Check(py); | 
					
						
							| 
									
										
										
											
												Implemented dynamic and multidimensional array support in RNA.
Example code: http://www.pasteall.org/7332/c.
New API functions: http://www.pasteall.org/7330/c.
Maximum number of dimensions is currently limited to 3, but can be increased arbitrarily if needed.
What this means for ID property access:
* MeshFace.verts - dynamic array, size 3 or 4 depending on MFace.v4
* MeshTextureFace.uv - dynamic, 2-dimensional array, size depends on MFace.v4
* Object.matrix - 2-dimensional array
What this means for functions:
* more intuitive API possibility, for example:
  Mesh.add_vertices([(x, y, z), (x, y, z), ...])
  Mesh.add_faces([(1, 2, 3), (4, 5, 6), ...])
Python part is not complete yet, e.g. it is possible to:
MeshFace.verts = (1, 2, 3) # even if Mesh.verts is (1, 2, 3, 4) and vice-versa
MeshTextureFace.uv = [(0.0, 0.0)] * 4 # only if a corresponding MFace is a quad
but the following won't work:
MeshTextureFace.uv[3] = (0.0, 0.0) # setting uv[3] modifies MTFace.uv[1][0] instead of MTFace.uv[3]
											
										 
											2009-08-25 17:06:36 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static int py_int_check(PyObject *py) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   /* accept only integers */ | 
					
						
							|  |  |  |   return PyLong_Check(py); | 
					
						
							| 
									
										
										
											
												Implemented dynamic and multidimensional array support in RNA.
Example code: http://www.pasteall.org/7332/c.
New API functions: http://www.pasteall.org/7330/c.
Maximum number of dimensions is currently limited to 3, but can be increased arbitrarily if needed.
What this means for ID property access:
* MeshFace.verts - dynamic array, size 3 or 4 depending on MFace.v4
* MeshTextureFace.uv - dynamic, 2-dimensional array, size depends on MFace.v4
* Object.matrix - 2-dimensional array
What this means for functions:
* more intuitive API possibility, for example:
  Mesh.add_vertices([(x, y, z), (x, y, z), ...])
  Mesh.add_faces([(1, 2, 3), (4, 5, 6), ...])
Python part is not complete yet, e.g. it is possible to:
MeshFace.verts = (1, 2, 3) # even if Mesh.verts is (1, 2, 3, 4) and vice-versa
MeshTextureFace.uv = [(0.0, 0.0)] * 4 # only if a corresponding MFace is a quad
but the following won't work:
MeshTextureFace.uv[3] = (0.0, 0.0) # setting uv[3] modifies MTFace.uv[1][0] instead of MTFace.uv[3]
											
										 
											2009-08-25 17:06:36 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static int py_bool_check(PyObject *py) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   return PyBool_Check(py); | 
					
						
							| 
									
										
										
										
											2009-09-06 15:13:57 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void float_set_index(PointerRNA *ptr, PropertyRNA *prop, int index, void *value) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   RNA_property_float_set_index(ptr, prop, index, *(float *)value); | 
					
						
							| 
									
										
										
										
											2009-09-06 15:13:57 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void int_set_index(PointerRNA *ptr, PropertyRNA *prop, int index, void *value) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   RNA_property_int_set_index(ptr, prop, index, *(int *)value); | 
					
						
							| 
									
										
										
										
											2009-09-06 15:13:57 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void bool_set_index(PointerRNA *ptr, PropertyRNA *prop, int index, void *value) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   RNA_property_boolean_set_index(ptr, prop, index, *(bool *)value); | 
					
						
							| 
									
										
										
										
											2009-09-06 15:13:57 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | static void convert_item_init_float(PointerRNA *ptr, | 
					
						
							|  |  |  |                                     PropertyRNA *prop, | 
					
						
							|  |  |  |                                     ItemConvert_FuncArg *convert_item) | 
					
						
							| 
									
										
										
										
											2016-03-08 15:33:28 +11:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   float *range = convert_item->arg.float_data.range; | 
					
						
							|  |  |  |   convert_item->func = py_to_float; | 
					
						
							|  |  |  |   RNA_property_float_range(ptr, prop, &range[0], &range[1]); | 
					
						
							| 
									
										
										
										
											2016-03-08 15:33:28 +11:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | static void convert_item_init_int(PointerRNA *ptr, | 
					
						
							|  |  |  |                                   PropertyRNA *prop, | 
					
						
							|  |  |  |                                   ItemConvert_FuncArg *convert_item) | 
					
						
							| 
									
										
										
										
											2016-03-08 15:33:28 +11:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   int *range = convert_item->arg.int_data.range; | 
					
						
							|  |  |  |   convert_item->func = py_to_int; | 
					
						
							|  |  |  |   RNA_property_int_range(ptr, prop, &range[0], &range[1]); | 
					
						
							| 
									
										
										
										
											2016-03-08 15:33:28 +11:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | static void convert_item_init_bool(PointerRNA *UNUSED(ptr), | 
					
						
							|  |  |  |                                    PropertyRNA *UNUSED(prop), | 
					
						
							|  |  |  |                                    ItemConvert_FuncArg *convert_item) | 
					
						
							| 
									
										
										
										
											2016-03-08 15:33:28 +11:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   convert_item->func = py_to_bool; | 
					
						
							| 
									
										
										
										
											2016-03-08 15:33:28 +11:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | int pyrna_py_to_array( | 
					
						
							|  |  |  |     PointerRNA *ptr, PropertyRNA *prop, char *param_data, PyObject *py, const char *error_prefix) | 
					
						
							| 
									
										
										
										
											2009-09-06 15:13:57 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   int ret; | 
					
						
							|  |  |  |   switch (RNA_property_type(prop)) { | 
					
						
							|  |  |  |     case PROP_FLOAT: { | 
					
						
							|  |  |  |       ItemConvert_FuncArg convert_item; | 
					
						
							|  |  |  |       convert_item_init_float(ptr, prop, &convert_item); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       ret = py_to_array(py, | 
					
						
							|  |  |  |                         ptr, | 
					
						
							|  |  |  |                         prop, | 
					
						
							|  |  |  |                         param_data, | 
					
						
							|  |  |  |                         py_float_check, | 
					
						
							|  |  |  |                         "float", | 
					
						
							|  |  |  |                         sizeof(float), | 
					
						
							|  |  |  |                         &convert_item, | 
					
						
							|  |  |  |                         (RNA_SetArrayFunc)RNA_property_float_set_array, | 
					
						
							|  |  |  |                         error_prefix); | 
					
						
							|  |  |  |       break; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     case PROP_INT: { | 
					
						
							|  |  |  |       ItemConvert_FuncArg convert_item; | 
					
						
							|  |  |  |       convert_item_init_int(ptr, prop, &convert_item); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       ret = py_to_array(py, | 
					
						
							|  |  |  |                         ptr, | 
					
						
							|  |  |  |                         prop, | 
					
						
							|  |  |  |                         param_data, | 
					
						
							|  |  |  |                         py_int_check, | 
					
						
							|  |  |  |                         "int", | 
					
						
							|  |  |  |                         sizeof(int), | 
					
						
							|  |  |  |                         &convert_item, | 
					
						
							|  |  |  |                         (RNA_SetArrayFunc)RNA_property_int_set_array, | 
					
						
							|  |  |  |                         error_prefix); | 
					
						
							|  |  |  |       break; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     case PROP_BOOLEAN: { | 
					
						
							|  |  |  |       ItemConvert_FuncArg convert_item; | 
					
						
							|  |  |  |       convert_item_init_bool(ptr, prop, &convert_item); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       ret = py_to_array(py, | 
					
						
							|  |  |  |                         ptr, | 
					
						
							|  |  |  |                         prop, | 
					
						
							|  |  |  |                         param_data, | 
					
						
							|  |  |  |                         py_bool_check, | 
					
						
							|  |  |  |                         "boolean", | 
					
						
							|  |  |  |                         sizeof(bool), | 
					
						
							|  |  |  |                         &convert_item, | 
					
						
							|  |  |  |                         (RNA_SetArrayFunc)RNA_property_boolean_set_array, | 
					
						
							|  |  |  |                         error_prefix); | 
					
						
							|  |  |  |       break; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     default: { | 
					
						
							|  |  |  |       PyErr_SetString(PyExc_TypeError, "not an array type"); | 
					
						
							|  |  |  |       ret = -1; | 
					
						
							|  |  |  |       break; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   return ret; | 
					
						
							| 
									
										
										
											
												Implemented dynamic and multidimensional array support in RNA.
Example code: http://www.pasteall.org/7332/c.
New API functions: http://www.pasteall.org/7330/c.
Maximum number of dimensions is currently limited to 3, but can be increased arbitrarily if needed.
What this means for ID property access:
* MeshFace.verts - dynamic array, size 3 or 4 depending on MFace.v4
* MeshTextureFace.uv - dynamic, 2-dimensional array, size depends on MFace.v4
* Object.matrix - 2-dimensional array
What this means for functions:
* more intuitive API possibility, for example:
  Mesh.add_vertices([(x, y, z), (x, y, z), ...])
  Mesh.add_faces([(1, 2, 3), (4, 5, 6), ...])
Python part is not complete yet, e.g. it is possible to:
MeshFace.verts = (1, 2, 3) # even if Mesh.verts is (1, 2, 3, 4) and vice-versa
MeshTextureFace.uv = [(0.0, 0.0)] * 4 # only if a corresponding MFace is a quad
but the following won't work:
MeshTextureFace.uv[3] = (0.0, 0.0) # setting uv[3] modifies MTFace.uv[1][0] instead of MTFace.uv[3]
											
										 
											2009-08-25 17:06:36 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | int pyrna_py_to_array_index(PointerRNA *ptr, | 
					
						
							|  |  |  |                             PropertyRNA *prop, | 
					
						
							|  |  |  |                             int arraydim, | 
					
						
							|  |  |  |                             int arrayoffset, | 
					
						
							|  |  |  |                             int index, | 
					
						
							|  |  |  |                             PyObject *py, | 
					
						
							|  |  |  |                             const char *error_prefix) | 
					
						
							| 
									
										
										
											
												Implemented dynamic and multidimensional array support in RNA.
Example code: http://www.pasteall.org/7332/c.
New API functions: http://www.pasteall.org/7330/c.
Maximum number of dimensions is currently limited to 3, but can be increased arbitrarily if needed.
What this means for ID property access:
* MeshFace.verts - dynamic array, size 3 or 4 depending on MFace.v4
* MeshTextureFace.uv - dynamic, 2-dimensional array, size depends on MFace.v4
* Object.matrix - 2-dimensional array
What this means for functions:
* more intuitive API possibility, for example:
  Mesh.add_vertices([(x, y, z), (x, y, z), ...])
  Mesh.add_faces([(1, 2, 3), (4, 5, 6), ...])
Python part is not complete yet, e.g. it is possible to:
MeshFace.verts = (1, 2, 3) # even if Mesh.verts is (1, 2, 3, 4) and vice-versa
MeshTextureFace.uv = [(0.0, 0.0)] * 4 # only if a corresponding MFace is a quad
but the following won't work:
MeshTextureFace.uv[3] = (0.0, 0.0) # setting uv[3] modifies MTFace.uv[1][0] instead of MTFace.uv[3]
											
										 
											2009-08-25 17:06:36 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   int ret; | 
					
						
							|  |  |  |   switch (RNA_property_type(prop)) { | 
					
						
							|  |  |  |     case PROP_FLOAT: { | 
					
						
							|  |  |  |       ItemConvert_FuncArg convert_item; | 
					
						
							|  |  |  |       convert_item_init_float(ptr, prop, &convert_item); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       ret = py_to_array_index(py, | 
					
						
							|  |  |  |                               ptr, | 
					
						
							|  |  |  |                               prop, | 
					
						
							|  |  |  |                               arraydim, | 
					
						
							|  |  |  |                               arrayoffset, | 
					
						
							|  |  |  |                               index, | 
					
						
							|  |  |  |                               py_float_check, | 
					
						
							|  |  |  |                               "float", | 
					
						
							|  |  |  |                               &convert_item, | 
					
						
							|  |  |  |                               float_set_index, | 
					
						
							|  |  |  |                               error_prefix); | 
					
						
							|  |  |  |       break; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     case PROP_INT: { | 
					
						
							|  |  |  |       ItemConvert_FuncArg convert_item; | 
					
						
							|  |  |  |       convert_item_init_int(ptr, prop, &convert_item); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       ret = py_to_array_index(py, | 
					
						
							|  |  |  |                               ptr, | 
					
						
							|  |  |  |                               prop, | 
					
						
							|  |  |  |                               arraydim, | 
					
						
							|  |  |  |                               arrayoffset, | 
					
						
							|  |  |  |                               index, | 
					
						
							|  |  |  |                               py_int_check, | 
					
						
							|  |  |  |                               "int", | 
					
						
							|  |  |  |                               &convert_item, | 
					
						
							|  |  |  |                               int_set_index, | 
					
						
							|  |  |  |                               error_prefix); | 
					
						
							|  |  |  |       break; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     case PROP_BOOLEAN: { | 
					
						
							|  |  |  |       ItemConvert_FuncArg convert_item; | 
					
						
							|  |  |  |       convert_item_init_bool(ptr, prop, &convert_item); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       ret = py_to_array_index(py, | 
					
						
							|  |  |  |                               ptr, | 
					
						
							|  |  |  |                               prop, | 
					
						
							|  |  |  |                               arraydim, | 
					
						
							|  |  |  |                               arrayoffset, | 
					
						
							|  |  |  |                               index, | 
					
						
							|  |  |  |                               py_bool_check, | 
					
						
							|  |  |  |                               "boolean", | 
					
						
							|  |  |  |                               &convert_item, | 
					
						
							|  |  |  |                               bool_set_index, | 
					
						
							|  |  |  |                               error_prefix); | 
					
						
							|  |  |  |       break; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     default: { | 
					
						
							|  |  |  |       PyErr_SetString(PyExc_TypeError, "not an array type"); | 
					
						
							|  |  |  |       ret = -1; | 
					
						
							|  |  |  |       break; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   return ret; | 
					
						
							| 
									
										
										
											
												Implemented dynamic and multidimensional array support in RNA.
Example code: http://www.pasteall.org/7332/c.
New API functions: http://www.pasteall.org/7330/c.
Maximum number of dimensions is currently limited to 3, but can be increased arbitrarily if needed.
What this means for ID property access:
* MeshFace.verts - dynamic array, size 3 or 4 depending on MFace.v4
* MeshTextureFace.uv - dynamic, 2-dimensional array, size depends on MFace.v4
* Object.matrix - 2-dimensional array
What this means for functions:
* more intuitive API possibility, for example:
  Mesh.add_vertices([(x, y, z), (x, y, z), ...])
  Mesh.add_faces([(1, 2, 3), (4, 5, 6), ...])
Python part is not complete yet, e.g. it is possible to:
MeshFace.verts = (1, 2, 3) # even if Mesh.verts is (1, 2, 3, 4) and vice-versa
MeshTextureFace.uv = [(0.0, 0.0)] * 4 # only if a corresponding MFace is a quad
but the following won't work:
MeshTextureFace.uv[3] = (0.0, 0.0) # setting uv[3] modifies MTFace.uv[1][0] instead of MTFace.uv[3]
											
										 
											2009-08-25 17:06:36 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-09-23 02:12:33 +00:00
										 |  |  | PyObject *pyrna_array_index(PointerRNA *ptr, PropertyRNA *prop, int index) | 
					
						
							| 
									
										
										
											
												Implemented dynamic and multidimensional array support in RNA.
Example code: http://www.pasteall.org/7332/c.
New API functions: http://www.pasteall.org/7330/c.
Maximum number of dimensions is currently limited to 3, but can be increased arbitrarily if needed.
What this means for ID property access:
* MeshFace.verts - dynamic array, size 3 or 4 depending on MFace.v4
* MeshTextureFace.uv - dynamic, 2-dimensional array, size depends on MFace.v4
* Object.matrix - 2-dimensional array
What this means for functions:
* more intuitive API possibility, for example:
  Mesh.add_vertices([(x, y, z), (x, y, z), ...])
  Mesh.add_faces([(1, 2, 3), (4, 5, 6), ...])
Python part is not complete yet, e.g. it is possible to:
MeshFace.verts = (1, 2, 3) # even if Mesh.verts is (1, 2, 3, 4) and vice-versa
MeshTextureFace.uv = [(0.0, 0.0)] * 4 # only if a corresponding MFace is a quad
but the following won't work:
MeshTextureFace.uv[3] = (0.0, 0.0) # setting uv[3] modifies MTFace.uv[1][0] instead of MTFace.uv[3]
											
										 
											2009-08-25 17:06:36 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   PyObject *item; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   switch (RNA_property_type(prop)) { | 
					
						
							|  |  |  |     case PROP_FLOAT: | 
					
						
							|  |  |  |       item = PyFloat_FromDouble(RNA_property_float_get_index(ptr, prop, index)); | 
					
						
							|  |  |  |       break; | 
					
						
							|  |  |  |     case PROP_BOOLEAN: | 
					
						
							|  |  |  |       item = PyBool_FromLong(RNA_property_boolean_get_index(ptr, prop, index)); | 
					
						
							|  |  |  |       break; | 
					
						
							|  |  |  |     case PROP_INT: | 
					
						
							|  |  |  |       item = PyLong_FromLong(RNA_property_int_get_index(ptr, prop, index)); | 
					
						
							|  |  |  |       break; | 
					
						
							|  |  |  |     default: | 
					
						
							|  |  |  |       PyErr_SetString(PyExc_TypeError, "not an array type"); | 
					
						
							|  |  |  |       item = NULL; | 
					
						
							|  |  |  |       break; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   return item; | 
					
						
							| 
									
										
										
											
												Implemented dynamic and multidimensional array support in RNA.
Example code: http://www.pasteall.org/7332/c.
New API functions: http://www.pasteall.org/7330/c.
Maximum number of dimensions is currently limited to 3, but can be increased arbitrarily if needed.
What this means for ID property access:
* MeshFace.verts - dynamic array, size 3 or 4 depending on MFace.v4
* MeshTextureFace.uv - dynamic, 2-dimensional array, size depends on MFace.v4
* Object.matrix - 2-dimensional array
What this means for functions:
* more intuitive API possibility, for example:
  Mesh.add_vertices([(x, y, z), (x, y, z), ...])
  Mesh.add_faces([(1, 2, 3), (4, 5, 6), ...])
Python part is not complete yet, e.g. it is possible to:
MeshFace.verts = (1, 2, 3) # even if Mesh.verts is (1, 2, 3, 4) and vice-versa
MeshTextureFace.uv = [(0.0, 0.0)] * 4 # only if a corresponding MFace is a quad
but the following won't work:
MeshTextureFace.uv[3] = (0.0, 0.0) # setting uv[3] modifies MTFace.uv[1][0] instead of MTFace.uv[3]
											
										 
											2009-08-25 17:06:36 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-09-06 15:13:57 +00:00
										 |  |  | #if 0
 | 
					
						
							|  |  |  | /* XXX this is not used (and never will?) */ | 
					
						
							|  |  |  | /* Given an array property, creates an N-dimensional tuple of values. */ | 
					
						
							| 
									
										
										
										
											2019-04-17 08:24:14 +02:00
										 |  |  | static PyObject *pyrna_py_from_array_internal(PointerRNA *ptr, | 
					
						
							|  |  |  |                                               PropertyRNA *prop, | 
					
						
							|  |  |  |                                               int dim, | 
					
						
							|  |  |  |                                               int *index) | 
					
						
							| 
									
										
										
											
												Implemented dynamic and multidimensional array support in RNA.
Example code: http://www.pasteall.org/7332/c.
New API functions: http://www.pasteall.org/7330/c.
Maximum number of dimensions is currently limited to 3, but can be increased arbitrarily if needed.
What this means for ID property access:
* MeshFace.verts - dynamic array, size 3 or 4 depending on MFace.v4
* MeshTextureFace.uv - dynamic, 2-dimensional array, size depends on MFace.v4
* Object.matrix - 2-dimensional array
What this means for functions:
* more intuitive API possibility, for example:
  Mesh.add_vertices([(x, y, z), (x, y, z), ...])
  Mesh.add_faces([(1, 2, 3), (4, 5, 6), ...])
Python part is not complete yet, e.g. it is possible to:
MeshFace.verts = (1, 2, 3) # even if Mesh.verts is (1, 2, 3, 4) and vice-versa
MeshTextureFace.uv = [(0.0, 0.0)] * 4 # only if a corresponding MFace is a quad
but the following won't work:
MeshTextureFace.uv[3] = (0.0, 0.0) # setting uv[3] modifies MTFace.uv[1][0] instead of MTFace.uv[3]
											
										 
											2009-08-25 17:06:36 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   PyObject *tuple; | 
					
						
							|  |  |  |   int i, len; | 
					
						
							|  |  |  |   int totdim = RNA_property_array_dimension(ptr, prop, NULL); | 
					
						
							| 
									
										
										
										
											2009-09-06 15:13:57 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   len = RNA_property_multi_array_length(ptr, prop, dim); | 
					
						
							| 
									
										
										
										
											2009-09-06 15:13:57 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   tuple = PyTuple_New(len); | 
					
						
							| 
									
										
										
										
											2009-09-06 15:13:57 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   for (i = 0; i < len; i++) { | 
					
						
							|  |  |  |     PyObject *item; | 
					
						
							| 
									
										
										
										
											2009-09-06 15:13:57 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |     if (dim + 1 < totdim) { | 
					
						
							|  |  |  |       item = pyrna_py_from_array_internal(ptr, prop, dim + 1, index); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     else { | 
					
						
							|  |  |  |       item = pyrna_array_index(ptr, prop, *index); | 
					
						
							|  |  |  |       *index = *index + 1; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2009-09-06 15:13:57 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |     if (!item) { | 
					
						
							|  |  |  |       Py_DECREF(tuple); | 
					
						
							|  |  |  |       return NULL; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2009-09-06 15:13:57 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |     PyTuple_SET_ITEM(tuple, i, item); | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2009-09-06 15:13:57 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   return tuple; | 
					
						
							| 
									
										
										
										
											2009-09-06 15:13:57 +00:00
										 |  |  | } | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | PyObject *pyrna_py_from_array_index(BPy_PropertyArrayRNA *self, | 
					
						
							|  |  |  |                                     PointerRNA *ptr, | 
					
						
							|  |  |  |                                     PropertyRNA *prop, | 
					
						
							|  |  |  |                                     int index) | 
					
						
							| 
									
										
										
										
											2009-09-06 15:13:57 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   int totdim, arraydim, arrayoffset, dimsize[MAX_ARRAY_DIMENSION], i, len; | 
					
						
							|  |  |  |   BPy_PropertyArrayRNA *ret = NULL; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   arraydim = self ? self->arraydim : 0; | 
					
						
							|  |  |  |   arrayoffset = self ? self->arrayoffset : 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   /* just in case check */ | 
					
						
							|  |  |  |   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 */ | 
					
						
							|  |  |  |     CLOG_WARN(BPY_LOG_RNA, "invalid index %d for array with length=%d", index, len); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     PyErr_SetString(PyExc_IndexError, "out of range"); | 
					
						
							|  |  |  |     return NULL; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   totdim = RNA_property_array_dimension(ptr, prop, dimsize); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (arraydim + 1 < totdim) { | 
					
						
							|  |  |  |     ret = (BPy_PropertyArrayRNA *)pyrna_prop_CreatePyObject(ptr, prop); | 
					
						
							|  |  |  |     ret->arraydim = arraydim + 1; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /* arr[3][4][5]
 | 
					
						
							|  |  |  |      * | 
					
						
							|  |  |  |      *    x = arr[2] | 
					
						
							|  |  |  |      *    index = 0 + 2 * 4 * 5 | 
					
						
							|  |  |  |      * | 
					
						
							|  |  |  |      *    x = arr[2][3] | 
					
						
							|  |  |  |      *    index = offset + 3 * 5 */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     for (i = arraydim + 1; i < totdim; i++) { | 
					
						
							|  |  |  |       index *= dimsize[i]; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     ret->arrayoffset = arrayoffset + index; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   else { | 
					
						
							|  |  |  |     index = arrayoffset + index; | 
					
						
							|  |  |  |     ret = (BPy_PropertyArrayRNA *)pyrna_array_index(ptr, prop, index); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   return (PyObject *)ret; | 
					
						
							| 
									
										
										
										
											2009-09-06 15:13:57 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | PyObject *pyrna_py_from_array(PointerRNA *ptr, PropertyRNA *prop) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   PyObject *ret; | 
					
						
							| 
									
										
										
										
											2009-09-06 15:13:57 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   ret = pyrna_math_object_from_array(ptr, prop); | 
					
						
							| 
									
										
										
										
											2009-09-06 15:13:57 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   /* is this a maths object? */ | 
					
						
							|  |  |  |   if (ret) { | 
					
						
							|  |  |  |     return ret; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2009-09-06 15:13:57 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   return pyrna_prop_CreatePyObject(ptr, prop); | 
					
						
							| 
									
										
										
											
												Implemented dynamic and multidimensional array support in RNA.
Example code: http://www.pasteall.org/7332/c.
New API functions: http://www.pasteall.org/7330/c.
Maximum number of dimensions is currently limited to 3, but can be increased arbitrarily if needed.
What this means for ID property access:
* MeshFace.verts - dynamic array, size 3 or 4 depending on MFace.v4
* MeshTextureFace.uv - dynamic, 2-dimensional array, size depends on MFace.v4
* Object.matrix - 2-dimensional array
What this means for functions:
* more intuitive API possibility, for example:
  Mesh.add_vertices([(x, y, z), (x, y, z), ...])
  Mesh.add_faces([(1, 2, 3), (4, 5, 6), ...])
Python part is not complete yet, e.g. it is possible to:
MeshFace.verts = (1, 2, 3) # even if Mesh.verts is (1, 2, 3, 4) and vice-versa
MeshTextureFace.uv = [(0.0, 0.0)] * 4 # only if a corresponding MFace is a quad
but the following won't work:
MeshTextureFace.uv[3] = (0.0, 0.0) # setting uv[3] modifies MTFace.uv[1][0] instead of MTFace.uv[3]
											
										 
											2009-08-25 17:06:36 +00:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2009-12-08 09:40:30 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | /* TODO, multi-dimensional arrays */ | 
					
						
							|  |  |  | int pyrna_array_contains_py(PointerRNA *ptr, PropertyRNA *prop, PyObject *value) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   int len = RNA_property_array_length(ptr, prop); | 
					
						
							|  |  |  |   int type; | 
					
						
							|  |  |  |   int i; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (len == 0) { | 
					
						
							|  |  |  |     /* possible with dynamic arrays */ | 
					
						
							|  |  |  |     return 0; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (RNA_property_array_dimension(ptr, prop, NULL) > 1) { | 
					
						
							|  |  |  |     PyErr_SetString(PyExc_TypeError, "PropertyRNA - multi dimensional arrays not supported yet"); | 
					
						
							|  |  |  |     return -1; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   type = RNA_property_type(prop); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   switch (type) { | 
					
						
							|  |  |  |     case PROP_FLOAT: { | 
					
						
							|  |  |  |       float value_f = PyFloat_AsDouble(value); | 
					
						
							|  |  |  |       if (value_f == -1 && PyErr_Occurred()) { | 
					
						
							|  |  |  |         PyErr_Clear(); | 
					
						
							|  |  |  |         return 0; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       else { | 
					
						
							|  |  |  |         float tmp[32]; | 
					
						
							|  |  |  |         float *tmp_arr; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (len * sizeof(float) > sizeof(tmp)) { | 
					
						
							|  |  |  |           tmp_arr = PyMem_MALLOC(len * sizeof(float)); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         else { | 
					
						
							|  |  |  |           tmp_arr = tmp; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         RNA_property_float_get_array(ptr, prop, tmp_arr); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         for (i = 0; i < len; i++) { | 
					
						
							|  |  |  |           if (tmp_arr[i] == value_f) { | 
					
						
							|  |  |  |             break; | 
					
						
							|  |  |  |           } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (tmp_arr != tmp) { | 
					
						
							|  |  |  |           PyMem_FREE(tmp_arr); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         return i < len ? 1 : 0; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       break; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     case PROP_INT: { | 
					
						
							|  |  |  |       int value_i = PyC_Long_AsI32(value); | 
					
						
							|  |  |  |       if (value_i == -1 && PyErr_Occurred()) { | 
					
						
							|  |  |  |         PyErr_Clear(); | 
					
						
							|  |  |  |         return 0; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       else { | 
					
						
							|  |  |  |         int tmp[32]; | 
					
						
							|  |  |  |         int *tmp_arr; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (len * sizeof(int) > sizeof(tmp)) { | 
					
						
							|  |  |  |           tmp_arr = PyMem_MALLOC(len * sizeof(int)); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         else { | 
					
						
							|  |  |  |           tmp_arr = tmp; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         RNA_property_int_get_array(ptr, prop, tmp_arr); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         for (i = 0; i < len; i++) { | 
					
						
							|  |  |  |           if (tmp_arr[i] == value_i) { | 
					
						
							|  |  |  |             break; | 
					
						
							|  |  |  |           } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (tmp_arr != tmp) { | 
					
						
							|  |  |  |           PyMem_FREE(tmp_arr); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         return i < len ? 1 : 0; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       break; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     case PROP_BOOLEAN: { | 
					
						
							|  |  |  |       int value_i = PyC_Long_AsBool(value); | 
					
						
							|  |  |  |       if (value_i == -1 && PyErr_Occurred()) { | 
					
						
							|  |  |  |         PyErr_Clear(); | 
					
						
							|  |  |  |         return 0; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       else { | 
					
						
							|  |  |  |         bool tmp[32]; | 
					
						
							|  |  |  |         bool *tmp_arr; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (len * sizeof(bool) > sizeof(tmp)) { | 
					
						
							|  |  |  |           tmp_arr = PyMem_MALLOC(len * sizeof(bool)); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         else { | 
					
						
							|  |  |  |           tmp_arr = tmp; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         RNA_property_boolean_get_array(ptr, prop, tmp_arr); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         for (i = 0; i < len; i++) { | 
					
						
							|  |  |  |           if (tmp_arr[i] == value_i) { | 
					
						
							|  |  |  |             break; | 
					
						
							|  |  |  |           } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (tmp_arr != tmp) { | 
					
						
							|  |  |  |           PyMem_FREE(tmp_arr); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         return i < len ? 1 : 0; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       break; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   /* should never reach this */ | 
					
						
							|  |  |  |   PyErr_SetString(PyExc_TypeError, "PropertyRNA - type not in float/bool/int"); | 
					
						
							|  |  |  |   return -1; | 
					
						
							| 
									
										
										
										
											2009-12-08 09:40:30 +00:00
										 |  |  | } |