Python part of multidim. array support for RNA complete.
Multidim. arrays can now be modified at any level, for example: struc.arrayprop = x struc.arrayprop[i] = x struc.arrayprop[i][j] = x struc.arrayprop[i][j][k] = x etc... Approriate rvalue type/length checking is done. To ensure all works correctly, I wrote automated tests in release/test/rna_array.py. These tests cover: array/item access, assignment on different levels, tests that proper exceptions are thrown on invalid item access/assignment. The tests use properties of the RNA Test struct defined in rna_test.c. This struct is only compiled when building with BF_UNIT_TEST=1 scons arg. Currently unit tests are run manually by loading the script in the Text Editor. Here's the output I have: http://www.pasteall.org/7644 Things to improve here: - better exception messages when multidim. array assignment fails. Those we have currently are not very useful for multidim. - add tests for slice assignment
This commit is contained in:
@@ -30,33 +30,65 @@
|
||||
|
||||
#include "BLI_string.h"
|
||||
|
||||
#include "BKE_global.h"
|
||||
|
||||
#include "MEM_guardedalloc.h"
|
||||
|
||||
typedef void (*ItemConvertFunc)(PyObject *, char *);
|
||||
typedef int (*ItemTypeCheckFunc)(PyObject *);
|
||||
typedef void (*RNA_SetArrayFunc)(PointerRNA *, PropertyRNA *, const char *);
|
||||
#define MAX_ARRAY_DIMENSION 10
|
||||
|
||||
/* Ensures that a python sequence has an expected number of items/sub-items and items are of expected type. */
|
||||
static int pyrna_validate_array(PyObject *seq, unsigned short dim, unsigned short totdim, unsigned short dim_size[],
|
||||
ItemTypeCheckFunc check_item_type, const char *item_type_str, char *error_str, int error_str_size)
|
||||
/* convenient way to access array dimension size */
|
||||
#define DIMSIZE(a) (dimsize[a - 1])
|
||||
|
||||
typedef void (*ItemConvertFunc)(PyObject *, char *);
|
||||
typedef int (*ItemTypeCheckFunc)(PyObject *);
|
||||
typedef void (*RNA_SetArrayFunc)(PointerRNA *, PropertyRNA *, const char *);
|
||||
typedef void (*RNA_SetIndexFunc)(PointerRNA *, PropertyRNA *, int index, void *);
|
||||
|
||||
/*
|
||||
arr[3][4][5]
|
||||
0 1 2 <- dimension index
|
||||
*/
|
||||
|
||||
/*
|
||||
arr[2] = x
|
||||
|
||||
py_to_array_index(arraydim=0, arrayoffset=0, index=2)
|
||||
validate_array(lvalue_dim=0)
|
||||
... make real index ...
|
||||
*/
|
||||
|
||||
/* arr[3]=x, self->arraydim is 0, lvalue_dim is 1 */
|
||||
/* Ensures that a python sequence has expected number of items/sub-items and items are of desired type. */
|
||||
static int validate_array_type(PyObject *seq, unsigned short dim, unsigned short totdim, unsigned short dimsize[],
|
||||
ItemTypeCheckFunc check_item_type, const char *item_type_str, const char *error_prefix)
|
||||
{
|
||||
int i;
|
||||
if (dim < totdim) {
|
||||
|
||||
/* not the last dimension */
|
||||
if (dim + 1 < totdim) {
|
||||
/* check that a sequence contains dimsize[dim] items */
|
||||
|
||||
for (i= 0; i < PySequence_Length(seq); i++) {
|
||||
PyObject *item;
|
||||
int ok= 1;
|
||||
item= PySequence_GetItem(seq, i);
|
||||
|
||||
if (!PySequence_Check(item)) {
|
||||
BLI_snprintf(error_str, error_str_size, "expected a %d-dimensional sequence of %s", (int)totdim, item_type_str);
|
||||
/* 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", error_prefix, item_type_str);
|
||||
ok= 0;
|
||||
}
|
||||
else if (PySequence_Length(item) != dim_size[dim - 1]) {
|
||||
BLI_snprintf(error_str, error_str_size, "dimension %d should contain %d items", (int)dim, (int)dim_size[dim - 1]);
|
||||
/* arr[3][4][5]
|
||||
DIMSIZE(1)=4
|
||||
DIMSIZE(2)=5
|
||||
|
||||
dim=0 */
|
||||
else if (PySequence_Length(item) != DIMSIZE(dim + 1)) {
|
||||
/* BLI_snprintf(error_str, error_str_size, "sequences of dimension %d should contain %d items", (int)dim + 1, (int)DIMSIZE(dim + 1)); */
|
||||
PyErr_Format(PyExc_ValueError, "%s sequences of dimension %d should contain %d items", error_prefix, (int)dim + 1, (int)DIMSIZE(dim + 1));
|
||||
ok= 0;
|
||||
}
|
||||
|
||||
if (!pyrna_validate_array(item, dim + 1, totdim, dim_size, check_item_type, item_type_str, error_str, error_str_size)) {
|
||||
else if (!validate_array_type(item, dim + 1, totdim, dimsize, check_item_type, item_type_str, error_prefix)) {
|
||||
ok= 0;
|
||||
}
|
||||
|
||||
@@ -67,13 +99,15 @@ static int pyrna_validate_array(PyObject *seq, unsigned short dim, unsigned shor
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* check that items are of correct type */
|
||||
for (i= 0; i < PySequence_Length(seq); i++) {
|
||||
PyObject *item= PySequence_GetItem(seq, i);
|
||||
|
||||
if (!check_item_type(item)) {
|
||||
Py_DECREF(item);
|
||||
|
||||
BLI_snprintf(error_str, error_str_size, "sequence items should be of type %s", item_type_str);
|
||||
|
||||
/* BLI_snprintf(error_str, error_str_size, "sequence items should be of type %s", item_type_str); */
|
||||
PyErr_Format(PyExc_TypeError, "sequence items should be of type %s", item_type_str);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -85,7 +119,7 @@ static int pyrna_validate_array(PyObject *seq, unsigned short dim, unsigned shor
|
||||
}
|
||||
|
||||
/* Returns the number of items in a single- or multi-dimensional sequence. */
|
||||
static int pyrna_count_items(PyObject *seq)
|
||||
static int count_items(PyObject *seq)
|
||||
{
|
||||
int totitem= 0;
|
||||
|
||||
@@ -93,7 +127,7 @@ static int pyrna_count_items(PyObject *seq)
|
||||
int i;
|
||||
for (i= 0; i < PySequence_Length(seq); i++) {
|
||||
PyObject *item= PySequence_GetItem(seq, i);
|
||||
totitem += pyrna_count_items(item);
|
||||
totitem += count_items(item);
|
||||
Py_DECREF(item);
|
||||
}
|
||||
}
|
||||
@@ -103,40 +137,103 @@ static int pyrna_count_items(PyObject *seq)
|
||||
return totitem;
|
||||
}
|
||||
|
||||
static int pyrna_apply_array_length(PointerRNA *ptr, PropertyRNA *prop, int totitem, char *error_str, int error_str_size)
|
||||
/* Modifies property array length if needed and PROP_DYNAMIC flag is set. */
|
||||
static int validate_array_length(PyObject *rvalue, PointerRNA *ptr, PropertyRNA *prop, int lvalue_dim, int *totitem, const char *error_prefix)
|
||||
{
|
||||
if (RNA_property_flag(prop) & PROP_DYNAMIC) {
|
||||
/* length can be flexible */
|
||||
if (RNA_property_array_length(ptr, prop) != totitem) {
|
||||
if (!RNA_property_dynamic_array_set_length(ptr, prop, totitem)) {
|
||||
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), totitem);
|
||||
unsigned short dimsize[MAX_ARRAY_DIMENSION];
|
||||
int tot, totdim, len;
|
||||
|
||||
tot= count_items(rvalue);
|
||||
totdim= RNA_property_array_dimension(prop, dimsize);
|
||||
|
||||
if ((RNA_property_flag(prop) & PROP_DYNAMIC) && lvalue_dim == 0) {
|
||||
/* length is flexible */
|
||||
if (RNA_property_array_length(ptr, prop) != tot) {
|
||||
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); */
|
||||
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);
|
||||
return 0;
|
||||
}
|
||||
|
||||
len= tot;
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* length is a constraint */
|
||||
int len= RNA_property_array_length(ptr, prop);
|
||||
if (totitem != len) {
|
||||
BLI_snprintf(error_str, error_str_size, "sequence must have length of %d", len);
|
||||
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 sequence must have %d items total", error_prefix, len);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
*totitem= len;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static char *pyrna_py_to_array(PyObject *seq, unsigned short dim, unsigned short totdim, char *data, unsigned int item_size, ItemConvertFunc convert_item)
|
||||
static int validate_array(PyObject *rvalue, PointerRNA *ptr, PropertyRNA *prop, int lvalue_dim, ItemTypeCheckFunc check_item_type, const char *item_type_str, int *totitem, const char *error_prefix)
|
||||
{
|
||||
unsigned short dimsize[MAX_ARRAY_DIMENSION];
|
||||
int totdim= RNA_property_array_dimension(prop, dimsize);
|
||||
|
||||
/* validate type first because length validation may modify property array length */
|
||||
|
||||
if (!validate_array_type(rvalue, lvalue_dim, totdim, dimsize, check_item_type, item_type_str, error_prefix))
|
||||
return 0;
|
||||
|
||||
return validate_array_length(rvalue, ptr, prop, lvalue_dim, totitem, error_prefix);
|
||||
}
|
||||
|
||||
static char *copy_values(PyObject *seq, PointerRNA *ptr, PropertyRNA *prop, unsigned short dim, char *data, unsigned int item_size, int *index, ItemConvertFunc convert_item, RNA_SetIndexFunc rna_set_index)
|
||||
{
|
||||
unsigned int i;
|
||||
int totdim= RNA_property_array_dimension(prop, NULL);
|
||||
|
||||
for (i= 0; i < PySequence_Length(seq); i++) {
|
||||
PyObject *item= PySequence_GetItem(seq, i);
|
||||
|
||||
if (dim < totdim) {
|
||||
data= pyrna_py_to_array(item, dim + 1, totdim, data, item_size, convert_item);
|
||||
if (dim + 1 < totdim) {
|
||||
data= copy_values(item, ptr, prop, dim + 1, data, item_size, index, convert_item, rna_set_index);
|
||||
}
|
||||
else {
|
||||
convert_item(item, data);
|
||||
data += item_size;
|
||||
if (!data) {
|
||||
char value[sizeof(int)];
|
||||
|
||||
convert_item(item, value);
|
||||
rna_set_index(ptr, prop, *index, value);
|
||||
*index = *index + 1;
|
||||
}
|
||||
else {
|
||||
convert_item(item, data);
|
||||
data += item_size;
|
||||
}
|
||||
}
|
||||
|
||||
Py_DECREF(item);
|
||||
@@ -145,21 +242,15 @@ static char *pyrna_py_to_array(PyObject *seq, unsigned short dim, unsigned short
|
||||
return data;
|
||||
}
|
||||
|
||||
static int pyrna_py_to_array_generic(PyObject *py, PointerRNA *ptr, PropertyRNA *prop, char *param_data, char *error_str, int error_str_size,
|
||||
ItemTypeCheckFunc check_item_type, const char *item_type_str, int item_size, ItemConvertFunc convert_item, RNA_SetArrayFunc rna_set_array)
|
||||
static int py_to_array(PyObject *py, PointerRNA *ptr, PropertyRNA *prop, char *param_data, ItemTypeCheckFunc check_item_type, const char *item_type_str, int item_size, ItemConvertFunc convert_item, RNA_SetArrayFunc rna_set_array, const char *error_prefix)
|
||||
{
|
||||
unsigned short totdim, dim_size[100];
|
||||
unsigned short totdim, dim_size[MAX_ARRAY_DIMENSION];
|
||||
int totitem;
|
||||
char *data= NULL;
|
||||
|
||||
totdim= RNA_property_array_dimension(prop, dim_size);
|
||||
|
||||
if (!pyrna_validate_array(py, 1, totdim, dim_size, check_item_type, item_type_str, error_str, error_str_size))
|
||||
return 0;
|
||||
|
||||
totitem= pyrna_count_items(py);
|
||||
|
||||
if (!pyrna_apply_array_length(ptr, prop, totitem, error_str, error_str_size))
|
||||
if (!validate_array(py, ptr, prop, 0, check_item_type, item_type_str, &totitem, error_prefix))
|
||||
return 0;
|
||||
|
||||
if (totitem) {
|
||||
@@ -168,7 +259,7 @@ static int pyrna_py_to_array_generic(PyObject *py, PointerRNA *ptr, PropertyRNA
|
||||
else
|
||||
data= param_data;
|
||||
|
||||
pyrna_py_to_array(py, 1, totdim, data, item_size, convert_item);
|
||||
copy_values(py, ptr, prop, 0, data, item_size, NULL, convert_item, NULL);
|
||||
|
||||
if (param_data) {
|
||||
if (RNA_property_flag(prop) & PROP_DYNAMIC) {
|
||||
@@ -186,50 +277,236 @@ static int pyrna_py_to_array_generic(PyObject *py, PointerRNA *ptr, PropertyRNA
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void pyrna_py_to_float(PyObject *py, char *data)
|
||||
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, ItemConvertFunc convert_item, RNA_SetIndexFunc rna_set_index, const char *error_prefix)
|
||||
{
|
||||
unsigned short totdim, dimsize[MAX_ARRAY_DIMENSION];
|
||||
int totitem, i;
|
||||
|
||||
totdim= RNA_property_array_dimension(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 (!validate_array(py, ptr, prop, lvalue_dim, check_item_type, item_type_str, &totitem, error_prefix))
|
||||
return 0;
|
||||
|
||||
if (totitem)
|
||||
copy_values(py, ptr, prop, lvalue_dim, NULL, 0, &index, convert_item, rna_set_index);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void py_to_float(PyObject *py, char *data)
|
||||
{
|
||||
*(float*)data= (float)PyFloat_AsDouble(py);
|
||||
}
|
||||
|
||||
static void pyrna_py_to_int(PyObject *py, char *data)
|
||||
static void py_to_int(PyObject *py, char *data)
|
||||
{
|
||||
*(int*)data= (int)PyLong_AsSsize_t(py);
|
||||
}
|
||||
|
||||
static void pyrna_py_to_boolean(PyObject *py, char *data)
|
||||
static void py_to_bool(PyObject *py, char *data)
|
||||
{
|
||||
*(int*)data= (int)PyObject_IsTrue(py);
|
||||
}
|
||||
|
||||
static int py_float_check(PyObject *py)
|
||||
{
|
||||
return PyFloat_Check(py) || (PyIndex_Check(py));
|
||||
/* accept both floats and integers */
|
||||
return PyFloat_Check(py) || PyLong_Check(py);
|
||||
}
|
||||
|
||||
static int py_int_check(PyObject *py)
|
||||
{
|
||||
return PyLong_Check(py) || (PyIndex_Check(py));
|
||||
/* accept only integers */
|
||||
return PyLong_Check(py);
|
||||
}
|
||||
|
||||
static int py_bool_check(PyObject *py)
|
||||
{
|
||||
return PyBool_Check(py) || (PyIndex_Check(py));
|
||||
return PyBool_Check(py);
|
||||
}
|
||||
|
||||
int pyrna_py_to_float_array(PyObject *py, PointerRNA *ptr, PropertyRNA *prop, char *param_data, char *error_str, int error_str_size)
|
||||
static void float_set_index(PointerRNA *ptr, PropertyRNA *prop, int index, void *value)
|
||||
{
|
||||
return pyrna_py_to_array_generic(py, ptr, prop, param_data, error_str, error_str_size,
|
||||
py_float_check, "float", sizeof(float), pyrna_py_to_float, (RNA_SetArrayFunc)RNA_property_float_set_array);
|
||||
RNA_property_float_set_index(ptr, prop, index, *(float*)value);
|
||||
}
|
||||
|
||||
int pyrna_py_to_int_array(PyObject *py, PointerRNA *ptr, PropertyRNA *prop, char *param_data, char *error_str, int error_str_size)
|
||||
static void int_set_index(PointerRNA *ptr, PropertyRNA *prop, int index, void *value)
|
||||
{
|
||||
return pyrna_py_to_array_generic(py, ptr, prop, param_data, error_str, error_str_size,
|
||||
py_int_check, "int", sizeof(int), pyrna_py_to_int, (RNA_SetArrayFunc)RNA_property_int_set_array);
|
||||
RNA_property_int_set_index(ptr, prop, index, *(int*)value);
|
||||
}
|
||||
|
||||
int pyrna_py_to_boolean_array(PyObject *py, PointerRNA *ptr, PropertyRNA *prop, char *param_data, char *error_str, int error_str_size)
|
||||
static void bool_set_index(PointerRNA *ptr, PropertyRNA *prop, int index, void *value)
|
||||
{
|
||||
return pyrna_py_to_array_generic(py, ptr, prop, param_data, error_str, error_str_size,
|
||||
py_bool_check, "boolean", sizeof(int), pyrna_py_to_boolean, (RNA_SetArrayFunc)RNA_property_boolean_set_array);
|
||||
RNA_property_boolean_set_index(ptr, prop, index, *(int*)value);
|
||||
}
|
||||
|
||||
int pyrna_py_to_array(PointerRNA *ptr, PropertyRNA *prop, char *param_data, PyObject *py, const char *error_prefix)
|
||||
{
|
||||
int ret;
|
||||
switch (RNA_property_type(prop)) {
|
||||
case PROP_FLOAT:
|
||||
ret= py_to_array(py, ptr, prop, param_data, py_float_check, "float", sizeof(float), py_to_float, (RNA_SetArrayFunc)RNA_property_float_set_array, error_prefix);
|
||||
break;
|
||||
case PROP_INT:
|
||||
ret= py_to_array(py, ptr, prop, param_data, py_int_check, "int", sizeof(int), py_to_int, (RNA_SetArrayFunc)RNA_property_int_set_array, error_prefix);
|
||||
break;
|
||||
case PROP_BOOLEAN:
|
||||
ret= py_to_array(py, ptr, prop, param_data, py_bool_check, "boolean", sizeof(int), py_to_bool, (RNA_SetArrayFunc)RNA_property_boolean_set_array, error_prefix);
|
||||
break;
|
||||
default:
|
||||
PyErr_SetString(PyExc_TypeError, "not an array type");
|
||||
ret= 0;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int pyrna_py_to_array_index(PointerRNA *ptr, PropertyRNA *prop, int arraydim, int arrayoffset, int index, PyObject *py, const char *error_prefix)
|
||||
{
|
||||
int ret;
|
||||
switch (RNA_property_type(prop)) {
|
||||
case PROP_FLOAT:
|
||||
ret= py_to_array_index(py, ptr, prop, arraydim, arrayoffset, index, py_float_check, "float", py_to_float, float_set_index, error_prefix);
|
||||
break;
|
||||
case PROP_INT:
|
||||
ret= py_to_array_index(py, ptr, prop, arraydim, arrayoffset, index, py_int_check, "int", py_to_int, int_set_index, error_prefix);
|
||||
break;
|
||||
case PROP_BOOLEAN:
|
||||
ret= py_to_array_index(py, ptr, prop, arraydim, arrayoffset, index, py_bool_check, "boolean", py_to_bool, bool_set_index, error_prefix);
|
||||
break;
|
||||
default:
|
||||
PyErr_SetString(PyExc_TypeError, "not an array type");
|
||||
ret= 0;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static PyObject *pyrna_array_item(PointerRNA *ptr, PropertyRNA *prop, int index)
|
||||
{
|
||||
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_FromSsize_t(RNA_property_int_get_index(ptr, prop, index));
|
||||
break;
|
||||
default:
|
||||
PyErr_SetString(PyExc_TypeError, "not an array type");
|
||||
item= NULL;
|
||||
}
|
||||
|
||||
return item;
|
||||
}
|
||||
|
||||
#if 0
|
||||
/* XXX this is not used (and never will?) */
|
||||
/* Given an array property, creates an N-dimensional tuple of values. */
|
||||
static PyObject *pyrna_py_from_array_internal(PointerRNA *ptr, PropertyRNA *prop, int dim, int *index)
|
||||
{
|
||||
PyObject *tuple;
|
||||
int i, len;
|
||||
int totdim= RNA_property_array_dimension(prop, NULL);
|
||||
|
||||
len= RNA_property_multidimensional_array_length(ptr, prop, dim);
|
||||
|
||||
tuple= PyTuple_New(len);
|
||||
|
||||
for (i= 0; i < len; i++) {
|
||||
PyObject *item;
|
||||
|
||||
if (dim + 1 < totdim)
|
||||
item= pyrna_py_from_array_internal(ptr, prop, dim + 1, index);
|
||||
else {
|
||||
item= pyrna_array_item(ptr, prop, *index);
|
||||
*index= *index + 1;
|
||||
}
|
||||
|
||||
if (!item) {
|
||||
Py_DECREF(tuple);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
PyTuple_SetItem(tuple, i, item);
|
||||
}
|
||||
|
||||
return tuple;
|
||||
}
|
||||
#endif
|
||||
|
||||
PyObject *pyrna_py_from_array_index(BPy_PropertyRNA *self, int index)
|
||||
{
|
||||
int totdim, i, len;
|
||||
unsigned short dimsize[MAX_ARRAY_DIMENSION];
|
||||
BPy_PropertyRNA *ret= NULL;
|
||||
|
||||
/* just in case check */
|
||||
len= RNA_property_multidimensional_array_length(&self->ptr, self->prop, self->arraydim);
|
||||
if (index >= len || index < 0) {
|
||||
/* this shouldn't happen because higher level funcs must check for invalid index */
|
||||
if (G.f & G_DEBUG) printf("pyrna_py_from_array_index: invalid index %d for array with length=%d\n", index, len);
|
||||
|
||||
PyErr_SetString(PyExc_IndexError, "out of range");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
totdim= RNA_property_array_dimension(self->prop, dimsize);
|
||||
|
||||
if (self->arraydim + 1 < totdim) {
|
||||
ret= (BPy_PropertyRNA*)pyrna_prop_CreatePyObject(&self->ptr, self->prop);
|
||||
ret->arraydim= self->arraydim + 1;
|
||||
|
||||
/* arr[3][4][5]
|
||||
|
||||
x = arr[2]
|
||||
index = 0 + 2 * 4 * 5
|
||||
|
||||
x = arr[2][3]
|
||||
index = offset + 3 * 5 */
|
||||
|
||||
for (i= self->arraydim + 1; i < totdim; i++)
|
||||
index *= DIMSIZE(i);
|
||||
|
||||
ret->arrayoffset= self->arrayoffset + index;
|
||||
}
|
||||
else {
|
||||
index = self->arrayoffset + index;
|
||||
ret= (BPy_PropertyRNA*)pyrna_array_item(&self->ptr, self->prop, index);
|
||||
}
|
||||
|
||||
return (PyObject*)ret;
|
||||
}
|
||||
|
||||
PyObject *pyrna_py_from_array(PointerRNA *ptr, PropertyRNA *prop)
|
||||
{
|
||||
PyObject *ret;
|
||||
|
||||
ret= pyrna_math_object_from_array(ptr, prop);
|
||||
|
||||
/* is this a maths object? */
|
||||
if (ret) return ret;
|
||||
|
||||
return pyrna_prop_CreatePyObject(ptr, prop);
|
||||
}
|
||||
|
||||
@@ -130,6 +130,70 @@ Mathutils_Callback mathutils_rna_matrix_cb = {
|
||||
(BaseMathSetIndexFunc) NULL
|
||||
};
|
||||
|
||||
PyObject *pyrna_math_object_from_array(PointerRNA *ptr, PropertyRNA *prop)
|
||||
{
|
||||
PyObject *ret= NULL;
|
||||
|
||||
#ifdef USE_MATHUTILS
|
||||
int type, subtype, totdim;
|
||||
int len;
|
||||
|
||||
len= RNA_property_array_length(ptr, prop);
|
||||
type= RNA_property_type(prop);
|
||||
subtype= RNA_property_subtype(prop);
|
||||
totdim= RNA_property_array_dimension(prop, NULL);
|
||||
|
||||
if (type != PROP_FLOAT) return NULL;
|
||||
|
||||
if (totdim == 1 || (totdim == 2 && subtype == PROP_MATRIX)) {
|
||||
ret = pyrna_prop_CreatePyObject(ptr, prop);
|
||||
|
||||
switch(RNA_property_subtype(prop)) {
|
||||
case PROP_TRANSLATION:
|
||||
case PROP_DIRECTION:
|
||||
case PROP_VELOCITY:
|
||||
case PROP_ACCELERATION:
|
||||
case PROP_XYZ:
|
||||
if(len>=2 && len <= 4) {
|
||||
PyObject *vec_cb= newVectorObject_cb(ret, len, mathutils_rna_array_cb_index, FALSE);
|
||||
Py_DECREF(ret); /* the vector owns now */
|
||||
ret= vec_cb; /* return the vector instead */
|
||||
}
|
||||
break;
|
||||
case PROP_MATRIX:
|
||||
if(len==16) {
|
||||
PyObject *mat_cb= newMatrixObject_cb(ret, 4,4, mathutils_rna_matrix_cb_index, FALSE);
|
||||
Py_DECREF(ret); /* the matrix owns now */
|
||||
ret= mat_cb; /* return the matrix instead */
|
||||
}
|
||||
else if (len==9) {
|
||||
PyObject *mat_cb= newMatrixObject_cb(ret, 3,3, mathutils_rna_matrix_cb_index, FALSE);
|
||||
Py_DECREF(ret); /* the matrix owns now */
|
||||
ret= mat_cb; /* return the matrix instead */
|
||||
}
|
||||
break;
|
||||
case PROP_EULER:
|
||||
case PROP_QUATERNION:
|
||||
if(len==3) { /* euler */
|
||||
PyObject *eul_cb= newEulerObject_cb(ret, mathutils_rna_array_cb_index, FALSE);
|
||||
Py_DECREF(ret); /* the matrix owns now */
|
||||
ret= eul_cb; /* return the matrix instead */
|
||||
}
|
||||
else if (len==4) {
|
||||
PyObject *quat_cb= newQuaternionObject_cb(ret, mathutils_rna_array_cb_index, FALSE);
|
||||
Py_DECREF(ret); /* the matrix owns now */
|
||||
ret= quat_cb; /* return the matrix instead */
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
static StructRNA *pyrna_struct_as_srna(PyObject *self);
|
||||
@@ -288,58 +352,7 @@ PyObject * pyrna_prop_to_py(PointerRNA *ptr, PropertyRNA *prop)
|
||||
int len = RNA_property_array_length(ptr, prop);
|
||||
|
||||
if (len > 0) {
|
||||
/* resolve the array from a new pytype */
|
||||
PyObject *ret = pyrna_prop_CreatePyObject(ptr, prop);
|
||||
|
||||
#ifdef USE_MATHUTILS
|
||||
|
||||
/* return a mathutils vector where possible */
|
||||
if(RNA_property_type(prop)==PROP_FLOAT) {
|
||||
switch(RNA_property_subtype(prop)) {
|
||||
case PROP_TRANSLATION:
|
||||
case PROP_DIRECTION:
|
||||
case PROP_VELOCITY:
|
||||
case PROP_ACCELERATION:
|
||||
case PROP_XYZ:
|
||||
if(len>=2 && len <= 4) {
|
||||
PyObject *vec_cb= newVectorObject_cb(ret, len, mathutils_rna_array_cb_index, FALSE);
|
||||
Py_DECREF(ret); /* the vector owns now */
|
||||
ret= vec_cb; /* return the vector instead */
|
||||
}
|
||||
break;
|
||||
case PROP_MATRIX:
|
||||
if(len==16) {
|
||||
PyObject *mat_cb= newMatrixObject_cb(ret, 4,4, mathutils_rna_matrix_cb_index, FALSE);
|
||||
Py_DECREF(ret); /* the matrix owns now */
|
||||
ret= mat_cb; /* return the matrix instead */
|
||||
}
|
||||
else if (len==9) {
|
||||
PyObject *mat_cb= newMatrixObject_cb(ret, 3,3, mathutils_rna_matrix_cb_index, FALSE);
|
||||
Py_DECREF(ret); /* the matrix owns now */
|
||||
ret= mat_cb; /* return the matrix instead */
|
||||
}
|
||||
break;
|
||||
case PROP_EULER:
|
||||
case PROP_QUATERNION:
|
||||
if(len==3) { /* euler */
|
||||
PyObject *eul_cb= newEulerObject_cb(ret, mathutils_rna_array_cb_index, FALSE);
|
||||
Py_DECREF(ret); /* the matrix owns now */
|
||||
ret= eul_cb; /* return the matrix instead */
|
||||
}
|
||||
else if (len==4) {
|
||||
PyObject *quat_cb= newQuaternionObject_cb(ret, mathutils_rna_array_cb_index, FALSE);
|
||||
Py_DECREF(ret); /* the matrix owns now */
|
||||
ret= quat_cb; /* return the matrix instead */
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
return ret;
|
||||
return pyrna_py_from_array(ptr, prop);
|
||||
}
|
||||
|
||||
/* see if we can coorce into a python type - PropertyType */
|
||||
@@ -511,7 +524,7 @@ int pyrna_py_to_prop(PointerRNA *ptr, PropertyRNA *prop, void *data, PyObject *v
|
||||
int len = RNA_property_array_length(ptr, prop);
|
||||
|
||||
if (len > 0) {
|
||||
char error_str[512];
|
||||
/* char error_str[512]; */
|
||||
int ok= 1;
|
||||
|
||||
#ifdef USE_MATHUTILS
|
||||
@@ -526,21 +539,10 @@ int pyrna_py_to_prop(PointerRNA *ptr, PropertyRNA *prop, void *data, PyObject *v
|
||||
return -1;
|
||||
}
|
||||
/* done getting the length */
|
||||
|
||||
/* for arrays we have a limited number of types */
|
||||
switch (type) {
|
||||
case PROP_BOOLEAN:
|
||||
ok= pyrna_py_to_boolean_array(value, ptr, prop, data, error_str, sizeof(error_str));
|
||||
break;
|
||||
case PROP_INT:
|
||||
ok= pyrna_py_to_int_array(value, ptr, prop, data, error_str, sizeof(error_str));
|
||||
break;
|
||||
case PROP_FLOAT:
|
||||
ok= pyrna_py_to_float_array(value, ptr, prop, data, error_str, sizeof(error_str));
|
||||
break;
|
||||
}
|
||||
ok= pyrna_py_to_array(ptr, prop, data, value, error_prefix);
|
||||
|
||||
if (!ok) {
|
||||
PyErr_Format(PyExc_AttributeError, "%.200s %s", error_prefix, error_str);
|
||||
/* PyErr_Format(PyExc_AttributeError, "%.200s %s", error_prefix, error_str); */
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
@@ -733,82 +735,84 @@ int pyrna_py_to_prop(PointerRNA *ptr, PropertyRNA *prop, void *data, PyObject *v
|
||||
return 0;
|
||||
}
|
||||
|
||||
static PyObject * pyrna_prop_to_py_index(PointerRNA *ptr, PropertyRNA *prop, int index)
|
||||
static PyObject * pyrna_prop_to_py_index(BPy_PropertyRNA *self, int index)
|
||||
{
|
||||
PyObject *ret;
|
||||
int type = RNA_property_type(prop);
|
||||
|
||||
/* see if we can coorce into a python type - PropertyType */
|
||||
switch (type) {
|
||||
case PROP_BOOLEAN:
|
||||
ret = PyBool_FromLong( RNA_property_boolean_get_index(ptr, prop, index) );
|
||||
break;
|
||||
case PROP_INT:
|
||||
ret = PyLong_FromSsize_t( (Py_ssize_t)RNA_property_int_get_index(ptr, prop, index) );
|
||||
break;
|
||||
case PROP_FLOAT:
|
||||
ret = PyFloat_FromDouble( RNA_property_float_get_index(ptr, prop, index) );
|
||||
break;
|
||||
default:
|
||||
PyErr_SetString(PyExc_AttributeError, "not an array type");
|
||||
ret = NULL;
|
||||
break;
|
||||
}
|
||||
|
||||
return ret;
|
||||
return pyrna_py_from_array_index(self, index);
|
||||
}
|
||||
|
||||
static int pyrna_py_to_prop_index(PointerRNA *ptr, PropertyRNA *prop, int index, PyObject *value)
|
||||
static int pyrna_py_to_prop_index(BPy_PropertyRNA *self, int index, PyObject *value)
|
||||
{
|
||||
int ret = 0;
|
||||
int totdim;
|
||||
PointerRNA *ptr= &self->ptr;
|
||||
PropertyRNA *prop= self->prop;
|
||||
int type = RNA_property_type(prop);
|
||||
|
||||
/* see if we can coorce into a python type - PropertyType */
|
||||
switch (type) {
|
||||
case PROP_BOOLEAN:
|
||||
{
|
||||
int param = PyObject_IsTrue( value );
|
||||
|
||||
totdim= RNA_property_array_dimension(prop, NULL);
|
||||
|
||||
if (totdim > 1) {
|
||||
/* char error_str[512]; */
|
||||
if (!pyrna_py_to_array_index(&self->ptr, self->prop, self->arraydim, self->arrayoffset, index, value, "")) {
|
||||
/* PyErr_SetString(PyExc_AttributeError, error_str); */
|
||||
ret= -1;
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* see if we can coorce into a python type - PropertyType */
|
||||
switch (type) {
|
||||
case PROP_BOOLEAN:
|
||||
{
|
||||
int param = PyObject_IsTrue( value );
|
||||
|
||||
if( param < 0 ) {
|
||||
PyErr_SetString(PyExc_TypeError, "expected True/False or 0/1");
|
||||
if( param < 0 ) {
|
||||
PyErr_SetString(PyExc_TypeError, "expected True/False or 0/1");
|
||||
ret = -1;
|
||||
} else {
|
||||
RNA_property_boolean_set_index(ptr, prop, index, param);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case PROP_INT:
|
||||
{
|
||||
int param = PyLong_AsSsize_t(value);
|
||||
if (PyErr_Occurred()) {
|
||||
PyErr_SetString(PyExc_TypeError, "expected an int type");
|
||||
ret = -1;
|
||||
} else {
|
||||
RNA_property_int_set_index(ptr, prop, index, param);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case PROP_FLOAT:
|
||||
{
|
||||
float param = PyFloat_AsDouble(value);
|
||||
if (PyErr_Occurred()) {
|
||||
PyErr_SetString(PyExc_TypeError, "expected a float type");
|
||||
ret = -1;
|
||||
} else {
|
||||
RNA_property_float_set_index(ptr, prop, index, param);
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
PyErr_SetString(PyExc_AttributeError, "not an array type");
|
||||
ret = -1;
|
||||
} else {
|
||||
RNA_property_boolean_set_index(ptr, prop, index, param);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case PROP_INT:
|
||||
{
|
||||
int param = PyLong_AsSsize_t(value);
|
||||
if (PyErr_Occurred()) {
|
||||
PyErr_SetString(PyExc_TypeError, "expected an int type");
|
||||
ret = -1;
|
||||
} else {
|
||||
RNA_property_int_set_index(ptr, prop, index, param);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case PROP_FLOAT:
|
||||
{
|
||||
float param = PyFloat_AsDouble(value);
|
||||
if (PyErr_Occurred()) {
|
||||
PyErr_SetString(PyExc_TypeError, "expected a float type");
|
||||
ret = -1;
|
||||
} else {
|
||||
RNA_property_float_set_index(ptr, prop, index, param);
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
PyErr_SetString(PyExc_AttributeError, "not an array type");
|
||||
ret = -1;
|
||||
break;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
//---------------sequence-------------------------------------------
|
||||
static int pyrna_prop_array_length(BPy_PropertyRNA *self)
|
||||
{
|
||||
if (RNA_property_array_dimension(self->prop, NULL) > 1)
|
||||
return RNA_property_multidimensional_array_length(&self->ptr, self->prop, self->arraydim);
|
||||
else
|
||||
return RNA_property_array_length(&self->ptr, self->prop);
|
||||
}
|
||||
|
||||
static Py_ssize_t pyrna_prop_len( BPy_PropertyRNA * self )
|
||||
{
|
||||
Py_ssize_t len;
|
||||
@@ -816,10 +820,10 @@ static Py_ssize_t pyrna_prop_len( BPy_PropertyRNA * self )
|
||||
if (RNA_property_type(self->prop) == PROP_COLLECTION) {
|
||||
len = RNA_property_collection_length(&self->ptr, self->prop);
|
||||
} else {
|
||||
len = RNA_property_array_length(&self->ptr, self->prop);
|
||||
len = pyrna_prop_array_length(self);
|
||||
|
||||
if (len==0) { /* not an array*/
|
||||
PyErr_SetString(PyExc_AttributeError, "len() only available for collection RNA types");
|
||||
PyErr_SetString(PyExc_AttributeError, "len() only available for collection and array RNA types");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
@@ -840,14 +844,15 @@ static PyObject *prop_subscript_collection_int(BPy_PropertyRNA * self, int keynu
|
||||
PyErr_Format(PyExc_IndexError, "index %d out of range", keynum);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static PyObject *prop_subscript_array_int(BPy_PropertyRNA * self, int keynum)
|
||||
{
|
||||
int len= RNA_property_array_length(&self->ptr, self->prop);
|
||||
int len= pyrna_prop_array_length(self);
|
||||
|
||||
if(keynum < 0) keynum += len;
|
||||
|
||||
if(keynum >= 0 && keynum < len)
|
||||
return pyrna_prop_to_py_index(&self->ptr, self->prop, keynum);
|
||||
return pyrna_prop_to_py_index(self, keynum);
|
||||
|
||||
PyErr_Format(PyExc_IndexError, "index %d out of range", keynum);
|
||||
return NULL;
|
||||
@@ -894,7 +899,7 @@ static PyObject *prop_subscript_array_slice(BPy_PropertyRNA * self, int start, i
|
||||
start = MIN2(start,stop); /* values are clamped from PySlice_GetIndicesEx */
|
||||
|
||||
for(count = start; count < stop; count++)
|
||||
PyList_SetItem(list, count - start, pyrna_prop_to_py_index(&self->ptr, self->prop, count));
|
||||
PyList_SetItem(list, count - start, pyrna_prop_to_py_index(self, count));
|
||||
|
||||
return list;
|
||||
}
|
||||
@@ -947,8 +952,8 @@ static PyObject *prop_subscript_array(BPy_PropertyRNA * self, PyObject *key)
|
||||
return prop_subscript_array_int(self, PyLong_AsSsize_t(key));
|
||||
}
|
||||
else if (PySlice_Check(key)) {
|
||||
int len= RNA_property_array_length(&self->ptr, self->prop);
|
||||
Py_ssize_t start, stop, step, slicelength;
|
||||
int len = pyrna_prop_array_length(self);
|
||||
|
||||
if (PySlice_GetIndicesEx((PySliceObject*)key, len, &start, &stop, &step, &slicelength) < 0)
|
||||
return NULL;
|
||||
@@ -974,13 +979,12 @@ static PyObject *pyrna_prop_subscript( BPy_PropertyRNA * self, PyObject *key )
|
||||
{
|
||||
if (RNA_property_type(self->prop) == PROP_COLLECTION) {
|
||||
return prop_subscript_collection(self, key);
|
||||
} else if (RNA_property_array_length(&self->ptr, self->prop)) { /* arrays are currently fixed length, zero length means its not an array */
|
||||
} else if (RNA_property_array_length(&self->ptr, self->prop)) { /* zero length means its not an array */
|
||||
return prop_subscript_array(self, key);
|
||||
} else {
|
||||
PyErr_SetString(PyExc_TypeError, "rna type is not an array or a collection");
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
PyErr_SetString(PyExc_TypeError, "rna type is not an array or a collection");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int prop_subscript_ass_array_slice(BPy_PropertyRNA * self, int begin, int end, PyObject *value)
|
||||
@@ -991,7 +995,7 @@ static int prop_subscript_ass_array_slice(BPy_PropertyRNA * self, int begin, int
|
||||
begin = MIN2(begin,end);
|
||||
|
||||
for(count = begin; count < end; count++) {
|
||||
if(pyrna_py_to_prop_index(&self->ptr, self->prop, count - begin, value) == -1) {
|
||||
if(pyrna_py_to_prop_index(self, count - begin, value) == -1) {
|
||||
/* TODO - this is wrong since some values have been assigned... will need to fix that */
|
||||
return -1; /* pyrna_struct_CreatePyObject should set the error */
|
||||
}
|
||||
@@ -1002,13 +1006,12 @@ static int prop_subscript_ass_array_slice(BPy_PropertyRNA * self, int begin, int
|
||||
|
||||
static int prop_subscript_ass_array_int(BPy_PropertyRNA * self, int keynum, PyObject *value)
|
||||
{
|
||||
|
||||
int len= RNA_property_array_length(&self->ptr, self->prop);
|
||||
int len= pyrna_prop_array_length(self);
|
||||
|
||||
if(keynum < 0) keynum += len;
|
||||
|
||||
if(keynum >= 0 && keynum < len)
|
||||
return pyrna_py_to_prop_index(&self->ptr, self->prop, keynum, value);
|
||||
return pyrna_py_to_prop_index(self, keynum, value);
|
||||
|
||||
PyErr_SetString(PyExc_IndexError, "out of range");
|
||||
return -1;
|
||||
@@ -1682,7 +1685,7 @@ PyObject *pyrna_prop_iter(BPy_PropertyRNA *self)
|
||||
|
||||
if (ret==NULL) {
|
||||
/* collection did not work, try array */
|
||||
int len = RNA_property_array_length(&self->ptr, self->prop);
|
||||
int len = pyrna_prop_array_length(self);
|
||||
|
||||
if (len) {
|
||||
int i;
|
||||
@@ -1690,7 +1693,7 @@ PyObject *pyrna_prop_iter(BPy_PropertyRNA *self)
|
||||
ret = PyList_New(len);
|
||||
|
||||
for (i=0; i < len; i++) {
|
||||
PyList_SET_ITEM(ret, i, pyrna_prop_to_py_index(&self->ptr, self->prop, i));
|
||||
PyList_SET_ITEM(ret, i, pyrna_prop_to_py_index(self, i));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1781,6 +1784,8 @@ PyObject *pyrna_param_to_py(PointerRNA *ptr, PropertyRNA *prop, void *data)
|
||||
/* resolve the array from a new pytype */
|
||||
ret = PyTuple_New(len);
|
||||
|
||||
/* kazanbas: TODO make multidim sequences here */
|
||||
|
||||
switch (type) {
|
||||
case PROP_BOOLEAN:
|
||||
for(a=0; a<len; a++)
|
||||
@@ -2445,6 +2450,9 @@ PyObject *pyrna_prop_CreatePyObject( PointerRNA *ptr, PropertyRNA *prop )
|
||||
|
||||
pyrna->ptr = *ptr;
|
||||
pyrna->prop = prop;
|
||||
|
||||
pyrna->arraydim= 0;
|
||||
pyrna->arrayoffset= 0;
|
||||
|
||||
return ( PyObject * ) pyrna;
|
||||
}
|
||||
|
||||
@@ -55,6 +55,10 @@ typedef struct {
|
||||
PyObject_HEAD /* required python macro */
|
||||
PointerRNA ptr;
|
||||
PropertyRNA *prop;
|
||||
|
||||
/* Arystan: this is a hack to allow sub-item r/w access like: face.uv[n][m] */
|
||||
int arraydim; /* array dimension, e.g: 0 for face.uv, 2 for face.uv[n][m], etc. */
|
||||
int arrayoffset; /* array first item offset, e.g. if face.uv is [4][2], arrayoffset for face.uv[n] is 2n */
|
||||
} BPy_PropertyRNA;
|
||||
|
||||
/* cheap trick */
|
||||
@@ -92,8 +96,11 @@ void pyrna_alloc_types(void);
|
||||
void pyrna_free_types(void);
|
||||
|
||||
/* primitive type conversion */
|
||||
int pyrna_py_to_boolean_array(PyObject *py, PointerRNA *ptr, PropertyRNA *prop, char *param_data, char *error_str, int error_str_size);
|
||||
int pyrna_py_to_int_array(PyObject *py, PointerRNA *ptr, PropertyRNA *prop, char *param_data, char *error_str, int error_str_size);
|
||||
int pyrna_py_to_float_array(PyObject *py, PointerRNA *ptr, PropertyRNA *prop, char *param_data, char *error_str, int error_str_size);
|
||||
int pyrna_py_to_array(PointerRNA *ptr, PropertyRNA *prop, char *param_data, PyObject *py, const char *error_prefix);
|
||||
int pyrna_py_to_array_index(PointerRNA *ptr, PropertyRNA *prop, int arraydim, int arrayoffset, int index, PyObject *py, const char *error_prefix);
|
||||
|
||||
PyObject *pyrna_py_from_array(PointerRNA *ptr, PropertyRNA *prop);
|
||||
PyObject *pyrna_py_from_array_index(BPy_PropertyRNA *self, int index);
|
||||
PyObject *pyrna_math_object_from_array(PointerRNA *ptr, PropertyRNA *prop);
|
||||
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user