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]
This commit is contained in:
@@ -441,19 +441,19 @@ static short animsys_write_rna_setting (PointerRNA *ptr, char *path, int array_i
|
||||
switch (RNA_property_type(prop))
|
||||
{
|
||||
case PROP_BOOLEAN:
|
||||
if (RNA_property_array_length(prop))
|
||||
if (RNA_property_array_length(&new_ptr, prop))
|
||||
RNA_property_boolean_set_index(&new_ptr, prop, array_index, (int)value);
|
||||
else
|
||||
RNA_property_boolean_set(&new_ptr, prop, (int)value);
|
||||
break;
|
||||
case PROP_INT:
|
||||
if (RNA_property_array_length(prop))
|
||||
if (RNA_property_array_length(&new_ptr, prop))
|
||||
RNA_property_int_set_index(&new_ptr, prop, array_index, (int)value);
|
||||
else
|
||||
RNA_property_int_set(&new_ptr, prop, (int)value);
|
||||
break;
|
||||
case PROP_FLOAT:
|
||||
if (RNA_property_array_length(prop))
|
||||
if (RNA_property_array_length(&new_ptr, prop))
|
||||
RNA_property_float_set_index(&new_ptr, prop, array_index, value);
|
||||
else
|
||||
RNA_property_float_set(&new_ptr, prop, value);
|
||||
@@ -1178,19 +1178,19 @@ void nladata_flush_channels (ListBase *channels)
|
||||
switch (RNA_property_type(prop))
|
||||
{
|
||||
case PROP_BOOLEAN:
|
||||
if (RNA_property_array_length(prop))
|
||||
if (RNA_property_array_length(ptr, prop))
|
||||
RNA_property_boolean_set_index(ptr, prop, array_index, (int)value);
|
||||
else
|
||||
RNA_property_boolean_set(ptr, prop, (int)value);
|
||||
break;
|
||||
case PROP_INT:
|
||||
if (RNA_property_array_length(prop))
|
||||
if (RNA_property_array_length(ptr, prop))
|
||||
RNA_property_int_set_index(ptr, prop, array_index, (int)value);
|
||||
else
|
||||
RNA_property_int_set(ptr, prop, (int)value);
|
||||
break;
|
||||
case PROP_FLOAT:
|
||||
if (RNA_property_array_length(prop))
|
||||
if (RNA_property_array_length(ptr, prop))
|
||||
RNA_property_float_set_index(ptr, prop, array_index, value);
|
||||
else
|
||||
RNA_property_float_set(ptr, prop, value);
|
||||
|
||||
@@ -698,19 +698,19 @@ float driver_get_target_value (ChannelDriver *driver, DriverTarget *dtar)
|
||||
if (RNA_path_resolve(&id_ptr, path, &ptr, &prop)) {
|
||||
switch (RNA_property_type(prop)) {
|
||||
case PROP_BOOLEAN:
|
||||
if (RNA_property_array_length(prop))
|
||||
if (RNA_property_array_length(&ptr, prop))
|
||||
value= (float)RNA_property_boolean_get_index(&ptr, prop, index);
|
||||
else
|
||||
value= (float)RNA_property_boolean_get(&ptr, prop);
|
||||
break;
|
||||
case PROP_INT:
|
||||
if (RNA_property_array_length(prop))
|
||||
if (RNA_property_array_length(&ptr, prop))
|
||||
value= (float)RNA_property_int_get_index(&ptr, prop, index);
|
||||
else
|
||||
value= (float)RNA_property_int_get(&ptr, prop);
|
||||
break;
|
||||
case PROP_FLOAT:
|
||||
if (RNA_property_array_length(prop))
|
||||
if (RNA_property_array_length(&ptr, prop))
|
||||
value= RNA_property_float_get_index(&ptr, prop, index);
|
||||
else
|
||||
value= RNA_property_float_get(&ptr, prop);
|
||||
|
||||
@@ -147,7 +147,7 @@ void getname_anim_fcurve(char *name, ID *id, FCurve *fcu)
|
||||
propname= (char *)RNA_property_ui_name(prop);
|
||||
|
||||
/* Array Index - only if applicable */
|
||||
if (RNA_property_array_length(prop)) {
|
||||
if (RNA_property_array_length(&ptr, prop)) {
|
||||
char c= RNA_property_array_item_char(prop, fcu->array_index);
|
||||
|
||||
/* we need to write the index to a temp buffer (in py syntax) */
|
||||
|
||||
@@ -157,7 +157,7 @@ short ANIM_add_driver (ID *id, const char rna_path[], int array_index, short fla
|
||||
/* fill in current value for python */
|
||||
if(type == DRIVER_TYPE_PYTHON) {
|
||||
PropertyType proptype= RNA_property_type(prop);
|
||||
int array= RNA_property_array_length(prop);
|
||||
int array= RNA_property_array_length(&ptr, prop);
|
||||
char *expression= fcu->driver->expression;
|
||||
int val, maxlen= sizeof(fcu->driver->expression);
|
||||
float fval;
|
||||
@@ -241,7 +241,7 @@ static int add_driver_button_exec (bContext *C, wmOperator *op)
|
||||
|
||||
if (path) {
|
||||
if (all) {
|
||||
length= RNA_property_array_length(prop);
|
||||
length= RNA_property_array_length(&ptr, prop);
|
||||
|
||||
if (length) index= 0;
|
||||
else length= 1;
|
||||
@@ -303,7 +303,7 @@ static int remove_driver_button_exec (bContext *C, wmOperator *op)
|
||||
|
||||
if (path) {
|
||||
if (all) {
|
||||
length= RNA_property_array_length(prop);
|
||||
length= RNA_property_array_length(&ptr, prop);
|
||||
|
||||
if(length) index= 0;
|
||||
else length= 1;
|
||||
|
||||
@@ -503,19 +503,19 @@ static float setting_get_rna_value (PointerRNA *ptr, PropertyRNA *prop, int inde
|
||||
|
||||
switch (RNA_property_type(prop)) {
|
||||
case PROP_BOOLEAN:
|
||||
if (RNA_property_array_length(prop))
|
||||
if (RNA_property_array_length(ptr, prop))
|
||||
value= (float)RNA_property_boolean_get_index(ptr, prop, index);
|
||||
else
|
||||
value= (float)RNA_property_boolean_get(ptr, prop);
|
||||
break;
|
||||
case PROP_INT:
|
||||
if (RNA_property_array_length(prop))
|
||||
if (RNA_property_array_length(ptr, prop))
|
||||
value= (float)RNA_property_int_get_index(ptr, prop, index);
|
||||
else
|
||||
value= (float)RNA_property_int_get(ptr, prop);
|
||||
break;
|
||||
case PROP_FLOAT:
|
||||
if (RNA_property_array_length(prop))
|
||||
if (RNA_property_array_length(ptr, prop))
|
||||
value= RNA_property_float_get_index(ptr, prop, index);
|
||||
else
|
||||
value= RNA_property_float_get(ptr, prop);
|
||||
@@ -1313,7 +1313,7 @@ static int insert_key_button_exec (bContext *C, wmOperator *op)
|
||||
|
||||
if (path) {
|
||||
if (all) {
|
||||
length= RNA_property_array_length(prop);
|
||||
length= RNA_property_array_length(&ptr, prop);
|
||||
|
||||
if(length) index= 0;
|
||||
else length= 1;
|
||||
@@ -1396,7 +1396,7 @@ static int delete_key_button_exec (bContext *C, wmOperator *op)
|
||||
|
||||
if (path) {
|
||||
if (all) {
|
||||
length= RNA_property_array_length(prop);
|
||||
length= RNA_property_array_length(&ptr, prop);
|
||||
|
||||
if(length) index= 0;
|
||||
else length= 1;
|
||||
|
||||
@@ -925,7 +925,7 @@ int modify_keyframes (bContext *C, ListBase *dsources, bAction *act, KeyingSet *
|
||||
|
||||
RNA_id_pointer_create(ksp->id, &id_ptr);
|
||||
if (RNA_path_resolve(&id_ptr, ksp->rna_path, &ptr, &prop) && prop)
|
||||
arraylen= RNA_property_array_length(prop);
|
||||
arraylen= RNA_property_array_length(&ptr, prop);
|
||||
}
|
||||
|
||||
/* we should do at least one step */
|
||||
@@ -1048,7 +1048,7 @@ int modify_keyframes (bContext *C, ListBase *dsources, bAction *act, KeyingSet *
|
||||
|
||||
RNA_id_pointer_create(cks->id, &id_ptr);
|
||||
if (RNA_path_resolve(&id_ptr, path, &ptr, &prop) && prop)
|
||||
arraylen= RNA_property_array_length(prop);
|
||||
arraylen= RNA_property_array_length(&ptr, prop);
|
||||
}
|
||||
|
||||
/* for each possible index, perform operation
|
||||
|
||||
@@ -1089,7 +1089,7 @@ void ui_get_but_vectorf(uiBut *but, float *vec)
|
||||
vec[0]= vec[1]= vec[2]= 0.0f;
|
||||
|
||||
if(RNA_property_type(prop) == PROP_FLOAT) {
|
||||
tot= RNA_property_array_length(prop);
|
||||
tot= RNA_property_array_length(&but->rnapoin, prop);
|
||||
tot= MIN2(tot, 3);
|
||||
|
||||
for(a=0; a<tot; a++)
|
||||
@@ -1123,7 +1123,7 @@ void ui_set_but_vectorf(uiBut *but, float *vec)
|
||||
prop= but->rnaprop;
|
||||
|
||||
if(RNA_property_type(prop) == PROP_FLOAT) {
|
||||
tot= RNA_property_array_length(prop);
|
||||
tot= RNA_property_array_length(&but->rnapoin, prop);
|
||||
tot= MIN2(tot, 3);
|
||||
|
||||
for(a=0; a<tot; a++)
|
||||
@@ -1181,19 +1181,19 @@ double ui_get_but_val(uiBut *but)
|
||||
|
||||
switch(RNA_property_type(prop)) {
|
||||
case PROP_BOOLEAN:
|
||||
if(RNA_property_array_length(prop))
|
||||
if(RNA_property_array_length(&but->rnapoin, prop))
|
||||
value= RNA_property_boolean_get_index(&but->rnapoin, prop, but->rnaindex);
|
||||
else
|
||||
value= RNA_property_boolean_get(&but->rnapoin, prop);
|
||||
break;
|
||||
case PROP_INT:
|
||||
if(RNA_property_array_length(prop))
|
||||
if(RNA_property_array_length(&but->rnapoin, prop))
|
||||
value= RNA_property_int_get_index(&but->rnapoin, prop, but->rnaindex);
|
||||
else
|
||||
value= RNA_property_int_get(&but->rnapoin, prop);
|
||||
break;
|
||||
case PROP_FLOAT:
|
||||
if(RNA_property_array_length(prop))
|
||||
if(RNA_property_array_length(&but->rnapoin, prop))
|
||||
value= RNA_property_float_get_index(&but->rnapoin, prop, but->rnaindex);
|
||||
else
|
||||
value= RNA_property_float_get(&but->rnapoin, prop);
|
||||
@@ -1245,19 +1245,19 @@ void ui_set_but_val(uiBut *but, double value)
|
||||
if(RNA_property_editable(&but->rnapoin, prop)) {
|
||||
switch(RNA_property_type(prop)) {
|
||||
case PROP_BOOLEAN:
|
||||
if(RNA_property_array_length(prop))
|
||||
if(RNA_property_array_length(&but->rnapoin, prop))
|
||||
RNA_property_boolean_set_index(&but->rnapoin, prop, but->rnaindex, value);
|
||||
else
|
||||
RNA_property_boolean_set(&but->rnapoin, prop, value);
|
||||
break;
|
||||
case PROP_INT:
|
||||
if(RNA_property_array_length(prop))
|
||||
if(RNA_property_array_length(&but->rnapoin, prop))
|
||||
RNA_property_int_set_index(&but->rnapoin, prop, but->rnaindex, value);
|
||||
else
|
||||
RNA_property_int_set(&but->rnapoin, prop, value);
|
||||
break;
|
||||
case PROP_FLOAT:
|
||||
if(RNA_property_array_length(prop))
|
||||
if(RNA_property_array_length(&but->rnapoin, prop))
|
||||
RNA_property_float_set_index(&but->rnapoin, prop, but->rnaindex, value);
|
||||
else
|
||||
RNA_property_float_set(&but->rnapoin, prop, value);
|
||||
@@ -2414,7 +2414,7 @@ uiBut *ui_def_but_rna(uiBlock *block, int type, int retval, char *str, short x1,
|
||||
but->rnapoin= *ptr;
|
||||
but->rnaprop= prop;
|
||||
|
||||
if(RNA_property_array_length(but->rnaprop))
|
||||
if(RNA_property_array_length(&but->rnapoin, but->rnaprop))
|
||||
but->rnaindex= index;
|
||||
else
|
||||
but->rnaindex= 0;
|
||||
|
||||
@@ -217,7 +217,7 @@ void ui_but_anim_menu(bContext *C, uiBut *but)
|
||||
pup= uiPupMenuBegin(C, RNA_property_ui_name(but->rnaprop), 0);
|
||||
layout= uiPupMenuLayout(pup);
|
||||
|
||||
length= RNA_property_array_length(but->rnaprop);
|
||||
length= RNA_property_array_length(&but->rnapoin, but->rnaprop);
|
||||
|
||||
if(but->flag & UI_BUT_ANIMATED_KEY) {
|
||||
if(length) {
|
||||
|
||||
@@ -760,7 +760,7 @@ void uiItemO(uiLayout *layout, char *name, int icon, char *opname)
|
||||
|
||||
/* RNA property items */
|
||||
|
||||
static void ui_item_rna_size(uiLayout *layout, char *name, int icon, PropertyRNA *prop, int index, int *r_w, int *r_h)
|
||||
static void ui_item_rna_size(uiLayout *layout, char *name, int icon, PointerRNA *ptr, PropertyRNA *prop, int index, int *r_w, int *r_h)
|
||||
{
|
||||
PropertyType type;
|
||||
PropertySubType subtype;
|
||||
@@ -769,7 +769,7 @@ static void ui_item_rna_size(uiLayout *layout, char *name, int icon, PropertyRNA
|
||||
/* arbitrary extended width by type */
|
||||
type= RNA_property_type(prop);
|
||||
subtype= RNA_property_subtype(prop);
|
||||
len= RNA_property_array_length(prop);
|
||||
len= RNA_property_array_length(ptr, prop);
|
||||
|
||||
if(ELEM3(type, PROP_STRING, PROP_POINTER, PROP_ENUM) && !name[0])
|
||||
name= "non-empty text";
|
||||
@@ -819,7 +819,7 @@ void uiItemFullR(uiLayout *layout, char *name, int icon, PointerRNA *ptr, Proper
|
||||
|
||||
/* retrieve info */
|
||||
type= RNA_property_type(prop);
|
||||
len= RNA_property_array_length(prop);
|
||||
len= RNA_property_array_length(ptr, prop);
|
||||
|
||||
/* set name and icon */
|
||||
if(!name)
|
||||
@@ -846,7 +846,7 @@ void uiItemFullR(uiLayout *layout, char *name, int icon, PointerRNA *ptr, Proper
|
||||
expand= (flag & UI_ITEM_R_EXPAND);
|
||||
|
||||
/* get size */
|
||||
ui_item_rna_size(layout, name, icon, prop, index, &w, &h);
|
||||
ui_item_rna_size(layout, name, icon, ptr, prop, index, &w, &h);
|
||||
|
||||
/* array property */
|
||||
if(index == RNA_NO_INDEX && len > 0)
|
||||
@@ -1132,7 +1132,7 @@ void uiItemPointerR(uiLayout *layout, char *name, int icon, struct PointerRNA *p
|
||||
/* create button */
|
||||
block= uiLayoutGetBlock(layout);
|
||||
|
||||
ui_item_rna_size(layout, name, icon, prop, 0, &w, &h);
|
||||
ui_item_rna_size(layout, name, icon, ptr, prop, 0, &w, &h);
|
||||
but= ui_item_with_label(layout, block, name, icon, ptr, prop, 0, 0, 0, w, h);
|
||||
|
||||
ui_but_add_search(but, ptr, prop, searchptr, searchprop);
|
||||
|
||||
@@ -1258,7 +1258,7 @@ void uiTemplateLayers(uiLayout *layout, PointerRNA *ptr, char *propname)
|
||||
* the 'remainder' is added to this, as it will be ok to have first row slightly wider if need be
|
||||
* - for now, only split into groups if if group will have at least 5 items
|
||||
*/
|
||||
layers= RNA_property_array_length(prop);
|
||||
layers= RNA_property_array_length(ptr, prop);
|
||||
cols= (layers / 2) + (layers % 2);
|
||||
groups= ((cols / 2) < 5) ? (1) : (cols / 2);
|
||||
|
||||
|
||||
@@ -72,7 +72,7 @@ uiBut *uiDefAutoButR(uiBlock *block, PointerRNA *ptr, PropertyRNA *prop, int ind
|
||||
{
|
||||
uiBut *but=NULL;
|
||||
const char *propname= RNA_property_identifier(prop);
|
||||
int arraylen= RNA_property_array_length(prop);
|
||||
int arraylen= RNA_property_array_length(ptr, prop);
|
||||
|
||||
switch(RNA_property_type(prop)) {
|
||||
case PROP_BOOLEAN: {
|
||||
@@ -81,7 +81,7 @@ uiBut *uiDefAutoButR(uiBlock *block, PointerRNA *ptr, PropertyRNA *prop, int ind
|
||||
if(arraylen && index == -1)
|
||||
return NULL;
|
||||
|
||||
length= RNA_property_array_length(prop);
|
||||
length= RNA_property_array_length(ptr, prop);
|
||||
|
||||
if(length)
|
||||
value= RNA_property_boolean_get_index(ptr, prop, index);
|
||||
|
||||
@@ -1084,7 +1084,7 @@ static TreeElement *outliner_add_element(SpaceOops *soops, ListBase *lb, void *i
|
||||
te->flag |= TE_LAZY_CLOSED;
|
||||
}
|
||||
else if(ELEM3(proptype, PROP_BOOLEAN, PROP_INT, PROP_FLOAT)) {
|
||||
tot= RNA_property_array_length(prop);
|
||||
tot= RNA_property_array_length(ptr, prop);
|
||||
|
||||
if(!(tselem->flag & TSE_CLOSED)) {
|
||||
for(a=0; a<tot; a++)
|
||||
@@ -3721,7 +3721,7 @@ static void tree_element_to_path(SpaceOops *soops, TreeElement *te, TreeStoreEle
|
||||
/* item is part of an array, so must set the array_index */
|
||||
*array_index= te->index;
|
||||
}
|
||||
else if (RNA_property_array_length(prop)) {
|
||||
else if (RNA_property_array_length(ptr, prop)) {
|
||||
/* entire array was selected, so keyframe all */
|
||||
*flag |= KSP_FLAG_WHOLE_ARRAY;
|
||||
}
|
||||
|
||||
@@ -581,8 +581,10 @@ PropertySubType RNA_property_subtype(PropertyRNA *prop);
|
||||
PropertyUnit RNA_property_unit(PropertyRNA *prop);
|
||||
int RNA_property_flag(PropertyRNA *prop);
|
||||
|
||||
int RNA_property_array_length(PropertyRNA *prop);
|
||||
int RNA_property_array_length(PointerRNA *ptr, PropertyRNA *prop);
|
||||
int RNA_property_dynamic_array_set_length(PointerRNA *ptr, PropertyRNA *prop, int length);
|
||||
char RNA_property_array_item_char(PropertyRNA *prop, int index);
|
||||
unsigned short RNA_property_array_dimension(PropertyRNA *prop, unsigned short dim_size[]);
|
||||
|
||||
int RNA_property_string_maxlength(PropertyRNA *prop);
|
||||
|
||||
|
||||
@@ -88,11 +88,15 @@ void RNA_def_enum_funcs(PropertyRNA *prop, EnumPropertyItemFunc itemfunc);
|
||||
PropertyRNA *RNA_def_float(StructOrFunctionRNA *cont, const char *identifier, float default_value, float hardmin, float hardmax, const char *ui_name, const char *ui_description, float softmin, float softmax);
|
||||
PropertyRNA *RNA_def_float_vector(StructOrFunctionRNA *cont, const char *identifier, int len, const float *default_value, float hardmin, float hardmax, const char *ui_name, const char *ui_description, float softmin, float softmax);
|
||||
PropertyRNA *RNA_def_float_color(StructOrFunctionRNA *cont, const char *identifier, int len, const float *default_value, float hardmin, float hardmax, const char *ui_name, const char *ui_description, float softmin, float softmax);
|
||||
PropertyRNA *RNA_def_float_matrix(StructOrFunctionRNA *cont, const char *identifier, int len, const float *default_value, float hardmin, float hardmax, const char *ui_name, const char *ui_description, float softmin, float softmax);
|
||||
PropertyRNA *RNA_def_float_matrix(StructOrFunctionRNA *cont, const char *identifier, int len, int rowsize, const float *default_value, float hardmin, float hardmax, const char *ui_name, const char *ui_description, float softmin, float softmax);
|
||||
PropertyRNA *RNA_def_float_rotation(StructOrFunctionRNA *cont, const char *identifier, int len, const float *default_value,
|
||||
float hardmin, float hardmax, const char *ui_name, const char *ui_description, float softmin, float softmax);
|
||||
PropertyRNA *RNA_def_float_array(StructOrFunctionRNA *cont, const char *identifier, int len, const float *default_value,
|
||||
float hardmin, float hardmax, const char *ui_name, const char *ui_description, float softmin, float softmax);
|
||||
/*
|
||||
PropertyRNA *RNA_def_float_dynamic_array(StructOrFunctionRNA *cont, const char *identifier, float hardmin, float hardmax,
|
||||
const char *ui_name, const char *ui_description, float softmin, float softmax, unsigned int dimension, unsigned short dim_size[]);
|
||||
*/
|
||||
PropertyRNA *RNA_def_float_percentage(StructOrFunctionRNA *cont, const char *identifier, float default_value, float hardmin, float hardmax,
|
||||
const char *ui_name, const char *ui_description, float softmin, float softmax);
|
||||
|
||||
@@ -123,6 +127,7 @@ void RNA_def_property_collection_sdna(PropertyRNA *prop, const char *structname,
|
||||
void RNA_def_property_flag(PropertyRNA *prop, int flag);
|
||||
void RNA_def_property_clear_flag(PropertyRNA *prop, int flag);
|
||||
void RNA_def_property_array(PropertyRNA *prop, int arraylength);
|
||||
void RNA_def_property_multidimensional_array(PropertyRNA *prop, int arraylength, unsigned short arraydimension, unsigned short dimsize[]);
|
||||
void RNA_def_property_range(PropertyRNA *prop, double min, double max);
|
||||
|
||||
void RNA_def_property_enum_items(PropertyRNA *prop, const EnumPropertyItem *item);
|
||||
@@ -146,6 +151,7 @@ void RNA_def_property_ui_icon(PropertyRNA *prop, int icon, int consecutive);
|
||||
void RNA_def_property_update(PropertyRNA *prop, int noteflag, const char *updatefunc);
|
||||
void RNA_def_property_editable_func(PropertyRNA *prop, const char *editable);
|
||||
|
||||
void RNA_def_property_dynamic_array_funcs(PropertyRNA *prop, const char *getlength, const char *setlength);
|
||||
void RNA_def_property_boolean_funcs(PropertyRNA *prop, const char *get, const char *set);
|
||||
void RNA_def_property_int_funcs(PropertyRNA *prop, const char *get, const char *set, const char *range);
|
||||
void RNA_def_property_float_funcs(PropertyRNA *prop, const char *get, const char *set, const char *range);
|
||||
|
||||
@@ -152,7 +152,8 @@ typedef enum PropertyFlag {
|
||||
PROP_IDPROPERTY = 1024,
|
||||
PROP_RAW_ACCESS = 8192,
|
||||
PROP_RAW_ARRAY = 16384,
|
||||
PROP_FREE_POINTERS = 32768
|
||||
PROP_FREE_POINTERS = 32768,
|
||||
PROP_DYNAMIC = 131072 /* for dynamic arrays, and retvals of type string */
|
||||
} PropertyFlag;
|
||||
|
||||
typedef struct CollectionPropertyIterator {
|
||||
|
||||
@@ -1724,6 +1724,14 @@ static void rna_generate_property(FILE *f, StructRNA *srna, const char *nest, Pr
|
||||
rna_print_c_string(f, prop->description); fprintf(f, ",\n\t");
|
||||
fprintf(f, "%d,\n", prop->icon);
|
||||
fprintf(f, "\t%s, %s|%s, %d,\n", rna_property_typename(prop->type), rna_property_subtypename(prop->subtype), rna_property_subtype_unit(prop->subtype), prop->arraylength);
|
||||
{
|
||||
int i;
|
||||
int tot= sizeof(prop->dimsize) / sizeof(prop->dimsize[0]);
|
||||
fprintf(f, "\t%s, %s, %d, {", rna_function_string(prop->getlength), rna_function_string(prop->setlength), (int)prop->arraydimension);
|
||||
for(i= 0; i < tot; i++) {
|
||||
fprintf(f, i == tot - 1 ? "%d},\n" : "%d, ", (int)prop->dimsize[i]);
|
||||
}
|
||||
}
|
||||
fprintf(f, "\t%s, %d, %s,\n", rna_function_string(prop->update), prop->noteflag, rna_function_string(prop->editable));
|
||||
|
||||
if(prop->flag & PROP_RAW_ACCESS) rna_set_raw_offset(f, srna, prop);
|
||||
|
||||
@@ -343,10 +343,11 @@ const char *rna_ensure_property_name(PropertyRNA *prop)
|
||||
return ((IDProperty*)prop)->name;
|
||||
}
|
||||
|
||||
int rna_ensure_property_array_length(PropertyRNA *prop)
|
||||
int rna_ensure_property_array_length(PointerRNA *ptr, PropertyRNA *prop)
|
||||
{
|
||||
if(prop->magic == RNA_MAGIC)
|
||||
return prop->arraylength;
|
||||
if(prop->magic == RNA_MAGIC) {
|
||||
return prop->getlength ? prop->getlength(ptr) : prop->arraylength;
|
||||
}
|
||||
else {
|
||||
IDProperty *idprop= (IDProperty*)prop;
|
||||
|
||||
@@ -549,9 +550,27 @@ int RNA_property_flag(PropertyRNA *prop)
|
||||
return rna_ensure_property(prop)->flag;
|
||||
}
|
||||
|
||||
int RNA_property_array_length(PropertyRNA *prop)
|
||||
int RNA_property_array_length(PointerRNA *ptr, PropertyRNA *prop)
|
||||
{
|
||||
return rna_ensure_property_array_length(prop);
|
||||
return rna_ensure_property_array_length(ptr, prop);
|
||||
}
|
||||
|
||||
int RNA_property_dynamic_array_set_length(PointerRNA *ptr, PropertyRNA *prop, int length)
|
||||
{
|
||||
if (prop->setlength)
|
||||
return prop->setlength(ptr, length);
|
||||
else
|
||||
prop->arraylength= length; /* function parameters only? */
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
unsigned short RNA_property_array_dimension(PropertyRNA *prop, unsigned short dimsize[])
|
||||
{
|
||||
if (dimsize && prop->arraydimension > 1) {
|
||||
memcpy(dimsize, prop->dimsize, sizeof(prop->dimsize[0]) * (prop->arraydimension - 1));
|
||||
}
|
||||
return prop->arraydimension;
|
||||
}
|
||||
|
||||
char RNA_property_array_item_char(PropertyRNA *prop, int index)
|
||||
@@ -1684,7 +1703,7 @@ static int rna_raw_access(ReportList *reports, PointerRNA *ptr, PropertyRNA *pro
|
||||
}
|
||||
|
||||
/* check item array */
|
||||
itemlen= RNA_property_array_length(itemprop);
|
||||
itemlen= RNA_property_array_length(&itemptr, itemprop);
|
||||
|
||||
/* try to access as raw array */
|
||||
if(RNA_property_collection_raw_array(ptr, prop, itemprop, &out)) {
|
||||
@@ -1736,7 +1755,7 @@ static int rna_raw_access(ReportList *reports, PointerRNA *ptr, PropertyRNA *pro
|
||||
iprop= RNA_struct_find_property(&itemptr, propname);
|
||||
|
||||
if(iprop) {
|
||||
itemlen= RNA_property_array_length(iprop);
|
||||
itemlen= RNA_property_array_length(&itemptr, iprop);
|
||||
itemtype= RNA_property_type(iprop);
|
||||
}
|
||||
else {
|
||||
@@ -2675,7 +2694,7 @@ char *RNA_pointer_as_string(PointerRNA *ptr)
|
||||
char *RNA_property_as_string(bContext *C, PointerRNA *ptr, PropertyRNA *prop)
|
||||
{
|
||||
int type = RNA_property_type(prop);
|
||||
int len = RNA_property_array_length(prop);
|
||||
int len = RNA_property_array_length(ptr, prop);
|
||||
int i;
|
||||
|
||||
DynStr *dynstr= BLI_dynstr_new();
|
||||
@@ -2905,6 +2924,12 @@ void RNA_parameter_list_free(ParameterList *parms)
|
||||
for(tot= 0; parm; parm= parm->next) {
|
||||
if(parm->type == PROP_COLLECTION)
|
||||
BLI_freelistN((ListBase*)((char*)parms->data+tot));
|
||||
else if (parm->flag & PROP_DYNAMIC) {
|
||||
/* for dynamic arrays and strings, data is a pointer to an array */
|
||||
char *array= *(char**)((char*)parms->data+tot);
|
||||
if(array)
|
||||
MEM_freeN(array);
|
||||
}
|
||||
|
||||
tot+= rna_parameter_size(parm);
|
||||
}
|
||||
@@ -3277,7 +3302,7 @@ int RNA_function_call_direct_va(bContext *C, ReportList *reports, PointerRNA *pt
|
||||
|
||||
type= RNA_property_type(parm);
|
||||
ftype= format[ofs++];
|
||||
len= RNA_property_array_length(parm);
|
||||
len= RNA_property_array_length(&funcptr, parm);
|
||||
alen= rna_function_format_array_length(format, ofs, flen);
|
||||
|
||||
if (len!=alen) {
|
||||
@@ -3342,7 +3367,7 @@ int RNA_function_call_direct_va(bContext *C, ReportList *reports, PointerRNA *pt
|
||||
|
||||
type= RNA_property_type(parm);
|
||||
ftype= format[ofs++];
|
||||
len= RNA_property_array_length(parm);
|
||||
len= RNA_property_array_length(&funcptr, parm);
|
||||
alen= rna_function_format_array_length(format, ofs, flen);
|
||||
|
||||
if (len!=alen) {
|
||||
|
||||
@@ -1028,6 +1028,26 @@ void RNA_def_property_array(PropertyRNA *prop, int arraylength)
|
||||
DefRNA.error= 1;
|
||||
break;
|
||||
}
|
||||
|
||||
prop->arraydimension= 1;
|
||||
}
|
||||
|
||||
void RNA_def_property_multidimensional_array(PropertyRNA *prop, int arraylength, unsigned short dimension, unsigned short dimsize[])
|
||||
{
|
||||
StructRNA *srna= DefRNA.laststruct;
|
||||
|
||||
if (dimension < 1 || dimension > RNA_MAX_ARRAY_DIMENSION) {
|
||||
fprintf(stderr, "RNA_def_property_multidimensional_array: %s.%s, array dimension must be between 1 and %d.\n", srna->identifier, prop->identifier, RNA_MAX_ARRAY_DIMENSION);
|
||||
DefRNA.error= 1;
|
||||
return;
|
||||
}
|
||||
|
||||
RNA_def_property_array(prop, arraylength);
|
||||
|
||||
prop->arraydimension= dimension;
|
||||
|
||||
if (dimension > 1)
|
||||
memcpy(prop->dimsize, dimsize, sizeof(dimsize[0]) * (dimension - 1));
|
||||
}
|
||||
|
||||
void RNA_def_property_ui_text(PropertyRNA *prop, const char *name, const char *description)
|
||||
@@ -1688,6 +1708,23 @@ void RNA_def_property_update(PropertyRNA *prop, int noteflag, const char *func)
|
||||
prop->update= (UpdateFunc)func;
|
||||
}
|
||||
|
||||
void RNA_def_property_dynamic_array_funcs(PropertyRNA *prop, const char *getlength, const char *setlength)
|
||||
{
|
||||
if(!DefRNA.preprocess) {
|
||||
fprintf(stderr, "RNA_def_property_*_funcs: only during preprocessing.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!(prop->flag & PROP_DYNAMIC)) {
|
||||
fprintf(stderr, "RNA_def_property_dynamic_array_funcs: property is a not dynamic array.\n");
|
||||
DefRNA.error= 1;
|
||||
return;
|
||||
}
|
||||
|
||||
if(getlength) prop->getlength= (PropArrayLengthGetFunc)getlength;
|
||||
if(setlength) prop->setlength= (PropArrayLengthSetFunc)setlength;
|
||||
}
|
||||
|
||||
void RNA_def_property_boolean_funcs(PropertyRNA *prop, const char *get, const char *set)
|
||||
{
|
||||
StructRNA *srna= DefRNA.laststruct;
|
||||
@@ -2085,14 +2122,15 @@ PropertyRNA *RNA_def_float_color(StructOrFunctionRNA *cont_, const char *identif
|
||||
}
|
||||
|
||||
|
||||
PropertyRNA *RNA_def_float_matrix(StructOrFunctionRNA *cont_, const char *identifier, int len, const float *default_value,
|
||||
PropertyRNA *RNA_def_float_matrix(StructOrFunctionRNA *cont_, const char *identifier, int len, int rowsize, const float *default_value,
|
||||
float hardmin, float hardmax, const char *ui_name, const char *ui_description, float softmin, float softmax)
|
||||
{
|
||||
ContainerRNA *cont= cont_;
|
||||
PropertyRNA *prop;
|
||||
unsigned short dimsize[1]= {rowsize};
|
||||
|
||||
prop= RNA_def_property(cont, identifier, PROP_FLOAT, PROP_MATRIX);
|
||||
if(len != 0) RNA_def_property_array(prop, len);
|
||||
if(len != 0) RNA_def_property_multidimensional_array(prop, len, 2, dimsize);
|
||||
if(default_value) RNA_def_property_float_array_default(prop, default_value);
|
||||
if(hardmin != hardmax) RNA_def_property_range(prop, hardmin, hardmax);
|
||||
RNA_def_property_ui_text(prop, ui_name, ui_description);
|
||||
@@ -2292,6 +2330,10 @@ int rna_parameter_size(PropertyRNA *parm)
|
||||
int len= parm->arraylength;
|
||||
|
||||
if(len > 0) {
|
||||
|
||||
if (parm->flag & PROP_DYNAMIC)
|
||||
return sizeof(void *);
|
||||
|
||||
switch (ptype) {
|
||||
case PROP_BOOLEAN:
|
||||
case PROP_INT:
|
||||
|
||||
@@ -40,6 +40,7 @@ struct IDProperty;
|
||||
struct GHash;
|
||||
|
||||
#define RNA_MAX_ARRAY 32
|
||||
#define RNA_MAX_ARRAY_DIMENSION 3
|
||||
|
||||
/* Function Callbacks */
|
||||
|
||||
@@ -49,6 +50,8 @@ typedef struct IDProperty* (*IDPropertiesFunc)(struct PointerRNA *ptr, int creat
|
||||
typedef struct StructRNA *(*StructRefineFunc)(struct PointerRNA *ptr);
|
||||
typedef char *(*StructPathFunc)(struct PointerRNA *ptr);
|
||||
|
||||
typedef int (*PropArrayLengthGetFunc)(struct PointerRNA *ptr);
|
||||
typedef int (*PropArrayLengthSetFunc)(struct PointerRNA *ptr, int length);
|
||||
typedef int (*PropBooleanGetFunc)(struct PointerRNA *ptr);
|
||||
typedef void (*PropBooleanSetFunc)(struct PointerRNA *ptr, int value);
|
||||
typedef void (*PropBooleanArrayGetFunc)(struct PointerRNA *ptr, int *values);
|
||||
@@ -131,6 +134,14 @@ struct PropertyRNA {
|
||||
PropertySubType subtype;
|
||||
/* if an array this is > 0, specifying the length */
|
||||
unsigned int arraylength;
|
||||
/* these, if non-NULL, override arraylength */
|
||||
PropArrayLengthGetFunc getlength;
|
||||
/* if NULL, length cannot be changed by a user */
|
||||
PropArrayLengthSetFunc setlength;
|
||||
/* used only for dynamic arrays for now, default 1 */
|
||||
unsigned short arraydimension;
|
||||
/* dimension sizes for dimensions greater than 1, first dimension size is not specified */
|
||||
unsigned short dimsize[RNA_MAX_ARRAY_DIMENSION - 1];
|
||||
|
||||
/* callback for updates on change */
|
||||
UpdateFunc update;
|
||||
|
||||
@@ -398,6 +398,51 @@ static void rna_MeshTextureFace_uv4_set(PointerRNA *ptr, const float *values)
|
||||
mtface->uv[3][1]= values[1];
|
||||
}
|
||||
|
||||
static int rna_CustomDataData_numverts(PointerRNA *ptr, int type)
|
||||
{
|
||||
Mesh *me= (Mesh*)ptr->id.data;
|
||||
CustomData *fdata= rna_mesh_fdata(me);
|
||||
CustomDataLayer *cdl;
|
||||
int a;
|
||||
size_t b;
|
||||
|
||||
for(cdl=fdata->layers, a=0; a<fdata->totlayer; cdl++, a++) {
|
||||
if(cdl->type == type) {
|
||||
b= ((char*)ptr->data - ((char*)cdl->data))/CustomData_sizeof(type);
|
||||
if(b >= 0 && b < me->totface)
|
||||
return (me->mface[b].v4? 4: 3);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int rna_MeshTextureFace_uv_get_length(PointerRNA *ptr)
|
||||
{
|
||||
return rna_CustomDataData_numverts(ptr, CD_MTFACE) * 2;
|
||||
}
|
||||
|
||||
static int rna_MeshTextureFace_uv_set_length(PointerRNA *ptr, int length)
|
||||
{
|
||||
return length == rna_MeshTextureFace_uv_get_length(ptr);
|
||||
}
|
||||
|
||||
static void rna_MeshTextureFace_uv_get(PointerRNA *ptr, float *values)
|
||||
{
|
||||
MTFace *mtface= (MTFace*)ptr->data;
|
||||
int totvert= rna_CustomDataData_numverts(ptr, CD_MTFACE);
|
||||
|
||||
memcpy(values, mtface->uv, totvert * 2 * sizeof(float));
|
||||
}
|
||||
|
||||
static void rna_MeshTextureFace_uv_set(PointerRNA *ptr, const float *values)
|
||||
{
|
||||
MTFace *mtface= (MTFace*)ptr->data;
|
||||
int totvert= rna_CustomDataData_numverts(ptr, CD_MTFACE);
|
||||
|
||||
memcpy(mtface->uv, values, totvert * 2 * sizeof(float));
|
||||
}
|
||||
|
||||
static void rna_MeshTextureFaceLayer_data_begin(CollectionPropertyIterator *iter, PointerRNA *ptr)
|
||||
{
|
||||
Mesh *me= (Mesh*)ptr->id.data;
|
||||
@@ -660,6 +705,40 @@ static void rna_TextureFace_image_set(PointerRNA *ptr, PointerRNA value)
|
||||
tf->tpage= (struct Image*)id;
|
||||
}
|
||||
|
||||
static int rna_MeshFace_verts_get_length(PointerRNA *ptr)
|
||||
{
|
||||
MFace *face= (MFace*)ptr->data;
|
||||
return face->v4 ? 4 : 3;
|
||||
}
|
||||
|
||||
static int rna_MeshFace_verts_set_length(PointerRNA *ptr, int length)
|
||||
{
|
||||
MFace *face= (MFace*)ptr->data;
|
||||
if (length == 3) {
|
||||
face->v4= 0;
|
||||
}
|
||||
else if(length == 4) {
|
||||
face->v4= 1;
|
||||
}
|
||||
else
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void rna_MeshFace_verts_get(PointerRNA *ptr, int *values)
|
||||
{
|
||||
MFace *face= (MFace*)ptr->data;
|
||||
int verts[4] = {face->v1, face->v2, face->v3, face->v4};
|
||||
memcpy(values, verts, (face->v4 ? 4 : 3) * sizeof(int));
|
||||
}
|
||||
|
||||
static void rna_MeshFace_verts_set(PointerRNA *ptr, const int *values)
|
||||
{
|
||||
MFace *face= (MFace*)ptr->data;
|
||||
memcpy(&face->v1, values, (face->v4 ? 4 : 3) * sizeof(int));
|
||||
}
|
||||
|
||||
/* path construction */
|
||||
|
||||
static char *rna_VertexGroupElement_path(PointerRNA *ptr)
|
||||
@@ -882,11 +961,21 @@ static void rna_def_mface(BlenderRNA *brna)
|
||||
RNA_def_struct_path_func(srna, "rna_MeshFace_path");
|
||||
RNA_def_struct_ui_icon(srna, ICON_FACESEL);
|
||||
|
||||
/*
|
||||
// XXX allows creating invalid meshes
|
||||
prop= RNA_def_property(srna, "verts", PROP_INT, PROP_UNSIGNED);
|
||||
RNA_def_property_int_sdna(prop, NULL, "v1");
|
||||
RNA_def_property_array(prop, 4);
|
||||
RNA_def_property_ui_text(prop, "Vertices", "Vertex indices");
|
||||
*/
|
||||
|
||||
// XXX allows creating invalid meshes
|
||||
prop= RNA_def_property(srna, "verts", PROP_INT, PROP_UNSIGNED);
|
||||
RNA_def_property_array(prop, 4);
|
||||
RNA_def_property_flag(prop, PROP_DYNAMIC);
|
||||
RNA_def_property_dynamic_array_funcs(prop, "rna_MeshFace_verts_get_length", "rna_MeshFace_verts_set_length");
|
||||
RNA_def_property_int_funcs(prop, "rna_MeshFace_verts_get", "rna_MeshFace_verts_set", NULL);
|
||||
RNA_def_property_ui_text(prop, "Vertices", "Vertex indices");
|
||||
|
||||
prop= RNA_def_property(srna, "material_index", PROP_INT, PROP_UNSIGNED);
|
||||
RNA_def_property_int_sdna(prop, NULL, "mat_nr");
|
||||
@@ -923,6 +1012,7 @@ static void rna_def_mtface(BlenderRNA *brna)
|
||||
{TF_ALPHA, "ALPHA", 0, "Alpha", "Render polygon transparent, depending on alpha channel of the texture"},
|
||||
{TF_CLIP, "CLIPALPHA", 0, "Clip Alpha", "Use the images alpha values clipped with no blending (binary alpha)"},
|
||||
{0, NULL, 0, NULL, NULL}};
|
||||
unsigned short uv_dim[1]= {2};
|
||||
|
||||
srna= RNA_def_struct(brna, "MeshTextureFaceLayer", NULL);
|
||||
RNA_def_struct_ui_text(srna, "Mesh Texture Face Layer", "Layer of texture faces in a Mesh datablock.");
|
||||
@@ -1041,6 +1131,13 @@ static void rna_def_mtface(BlenderRNA *brna)
|
||||
RNA_def_property_array(prop, 2);
|
||||
RNA_def_property_float_funcs(prop, "rna_MeshTextureFace_uv4_get", "rna_MeshTextureFace_uv4_set", NULL);
|
||||
RNA_def_property_ui_text(prop, "UV 4", "");
|
||||
|
||||
prop= RNA_def_property(srna, "uv", PROP_FLOAT, PROP_XYZ);
|
||||
RNA_def_property_multidimensional_array(prop, 4 * 2, 2, uv_dim);
|
||||
RNA_def_property_flag(prop, PROP_DYNAMIC);
|
||||
RNA_def_property_dynamic_array_funcs(prop, "rna_MeshTextureFace_uv_get_length", "rna_MeshTextureFace_uv_set_length");
|
||||
RNA_def_property_float_funcs(prop, "rna_MeshTextureFace_uv_get", "rna_MeshTextureFace_uv_set", NULL);
|
||||
RNA_def_property_ui_text(prop, "UV", "");
|
||||
}
|
||||
|
||||
static void rna_def_msticky(BlenderRNA *brna)
|
||||
|
||||
@@ -1029,6 +1029,8 @@ static void rna_def_object(BlenderRNA *brna)
|
||||
{OB_DUPLIGROUP, "GROUP", 0, "Group", "Enable group instancing."},
|
||||
{0, NULL, 0, NULL, NULL}};
|
||||
|
||||
unsigned short matrix_dimsize[]= {4};
|
||||
|
||||
srna= RNA_def_struct(brna, "Object", "ID");
|
||||
RNA_def_struct_ui_text(srna, "Object", "Object datablock defining an object in a scene..");
|
||||
RNA_def_struct_clear_flag(srna, STRUCT_ID_REFCOUNT);
|
||||
@@ -1190,7 +1192,7 @@ static void rna_def_object(BlenderRNA *brna)
|
||||
/* matrix */
|
||||
prop= RNA_def_property(srna, "matrix", PROP_FLOAT, PROP_MATRIX);
|
||||
RNA_def_property_float_sdna(prop, NULL, "obmat");
|
||||
RNA_def_property_array(prop, 16);
|
||||
RNA_def_property_multidimensional_array(prop, 16, 2, matrix_dimsize);
|
||||
RNA_def_property_ui_text(prop, "Matrix", "Transformation matrix.");
|
||||
|
||||
/* collections */
|
||||
|
||||
235
source/blender/python/intern/bpy_array.c
Normal file
235
source/blender/python/intern/bpy_array.c
Normal file
@@ -0,0 +1,235 @@
|
||||
/**
|
||||
*
|
||||
*
|
||||
* ***** BEGIN GPL LICENSE BLOCK *****
|
||||
*
|
||||
* 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,
|
||||
* Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*
|
||||
* Contributor(s): Arystanbek Dyussenov
|
||||
*
|
||||
* ***** END GPL LICENSE BLOCK *****
|
||||
*/
|
||||
|
||||
#include "Python.h"
|
||||
|
||||
#include "bpy_rna.h"
|
||||
|
||||
#include "RNA_access.h"
|
||||
|
||||
#include "BLI_string.h"
|
||||
|
||||
#include "MEM_guardedalloc.h"
|
||||
|
||||
typedef void (*ItemConvertFunc)(PyObject *, char *);
|
||||
typedef int (*ItemTypeCheckFunc)(PyObject *);
|
||||
typedef void (*RNA_SetArrayFunc)(PointerRNA *, PropertyRNA *, const char *);
|
||||
|
||||
/* 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)
|
||||
{
|
||||
int i;
|
||||
if (dim < totdim) {
|
||||
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);
|
||||
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]);
|
||||
ok= 0;
|
||||
}
|
||||
|
||||
if (!pyrna_validate_array(item, dim + 1, totdim, dim_size, check_item_type, item_type_str, error_str, error_str_size)) {
|
||||
ok= 0;
|
||||
}
|
||||
|
||||
Py_DECREF(item);
|
||||
|
||||
if (!ok)
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
else {
|
||||
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);
|
||||
return 0;
|
||||
}
|
||||
|
||||
Py_DECREF(item);
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Returns the number of items in a single- or multi-dimensional sequence. */
|
||||
static int pyrna_count_items(PyObject *seq)
|
||||
{
|
||||
int totitem= 0;
|
||||
|
||||
if (PySequence_Check(seq)) {
|
||||
int i;
|
||||
for (i= 0; i < PySequence_Length(seq); i++) {
|
||||
PyObject *item= PySequence_GetItem(seq, i);
|
||||
totitem += pyrna_count_items(item);
|
||||
Py_DECREF(item);
|
||||
}
|
||||
}
|
||||
else
|
||||
totitem= 1;
|
||||
|
||||
return totitem;
|
||||
}
|
||||
|
||||
static int pyrna_apply_array_length(PointerRNA *ptr, PropertyRNA *prop, int totitem, char *error_str, int error_str_size)
|
||||
{
|
||||
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);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
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);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
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)
|
||||
{
|
||||
unsigned int i;
|
||||
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);
|
||||
}
|
||||
else {
|
||||
convert_item(item, data);
|
||||
data += item_size;
|
||||
}
|
||||
|
||||
Py_DECREF(item);
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
unsigned short totdim, dim_size[100];
|
||||
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))
|
||||
return 0;
|
||||
|
||||
if (totitem) {
|
||||
if (!param_data || RNA_property_flag(prop) & PROP_DYNAMIC)
|
||||
data= MEM_callocN(item_size * totitem, "pyrna primitive type array");
|
||||
else
|
||||
data= param_data;
|
||||
|
||||
pyrna_py_to_array(py, 1, totdim, data, item_size, convert_item);
|
||||
|
||||
if (param_data) {
|
||||
if (RNA_property_flag(prop) & PROP_DYNAMIC) {
|
||||
/* not freeing allocated mem, RNA_parameter_list_free will do this */
|
||||
*(char**)param_data= data;
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* NULL can only pass through in case RNA property arraylength is 0 (impossible?) */
|
||||
rna_set_array(ptr, prop, data);
|
||||
MEM_freeN(data);
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void pyrna_py_to_float(PyObject *py, char *data)
|
||||
{
|
||||
*(float*)data= (float)PyFloat_AsDouble(py);
|
||||
}
|
||||
|
||||
static void pyrna_py_to_int(PyObject *py, char *data)
|
||||
{
|
||||
*(int*)data= (int)PyLong_AsSsize_t(py);
|
||||
}
|
||||
|
||||
static void pyrna_py_to_boolean(PyObject *py, char *data)
|
||||
{
|
||||
*(int*)data= (int)PyObject_IsTrue(py);
|
||||
}
|
||||
|
||||
static int py_float_check(PyObject *py)
|
||||
{
|
||||
return PyFloat_Check(py);
|
||||
}
|
||||
|
||||
static int py_int_check(PyObject *py)
|
||||
{
|
||||
return PyLong_Check(py);
|
||||
}
|
||||
|
||||
static int py_bool_check(PyObject *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)
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
int pyrna_py_to_int_array(PyObject *py, PointerRNA *ptr, PropertyRNA *prop, char *param_data, char *error_str, int error_str_size)
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
int pyrna_py_to_boolean_array(PyObject *py, PointerRNA *ptr, PropertyRNA *prop, char *param_data, char *error_str, int error_str_size)
|
||||
{
|
||||
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);
|
||||
}
|
||||
@@ -246,7 +246,7 @@ PyObject * pyrna_prop_to_py(PointerRNA *ptr, PropertyRNA *prop)
|
||||
{
|
||||
PyObject *ret;
|
||||
int type = RNA_property_type(prop);
|
||||
int len = RNA_property_array_length(prop);
|
||||
int len = RNA_property_array_length(ptr, prop);
|
||||
|
||||
if (len > 0) {
|
||||
/* resolve the array from a new pytype */
|
||||
@@ -469,128 +469,43 @@ int pyrna_py_to_prop(PointerRNA *ptr, PropertyRNA *prop, void *data, PyObject *v
|
||||
{
|
||||
/* XXX hard limits should be checked here */
|
||||
int type = RNA_property_type(prop);
|
||||
int len = RNA_property_array_length(prop);
|
||||
int len = RNA_property_array_length(ptr, prop);
|
||||
|
||||
if (len > 0) {
|
||||
PyObject *item;
|
||||
int py_len = -1;
|
||||
int i;
|
||||
|
||||
char error_str[512];
|
||||
int ok= 1;
|
||||
|
||||
#ifdef USE_MATHUTILS
|
||||
if(MatrixObject_Check(value)) {
|
||||
MatrixObject *mat = (MatrixObject*)value;
|
||||
if(!BaseMath_ReadCallback(mat))
|
||||
return -1;
|
||||
|
||||
py_len = mat->rowSize * mat->colSize;
|
||||
} else /* continue... */
|
||||
#endif
|
||||
if (PySequence_Check(value)) {
|
||||
py_len= (int)PySequence_Length(value);
|
||||
}
|
||||
else {
|
||||
if (!PySequence_Check(value)) {
|
||||
PyErr_Format(PyExc_TypeError, "%.200s RNA array assignment expected a sequence instead of %.200s instance.", error_prefix, Py_TYPE(value)->tp_name);
|
||||
return -1;
|
||||
}
|
||||
/* done getting the length */
|
||||
|
||||
if (py_len != len) {
|
||||
PyErr_Format(PyExc_TypeError, "%.200s python sequence length %d did not match the RNA array length %d.", error_prefix, py_len, len);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* for arrays we have a limited number of types */
|
||||
switch (type) {
|
||||
case PROP_BOOLEAN:
|
||||
{
|
||||
int *param_arr;
|
||||
if(data) param_arr= (int*)data;
|
||||
else param_arr= MEM_mallocN(sizeof(int) * len, "pyrna bool array");
|
||||
|
||||
|
||||
/* collect the variables before assigning, incase one of them is incorrect */
|
||||
for (i=0; i<len; i++) {
|
||||
item = PySequence_GetItem(value, i);
|
||||
param_arr[i] = PyObject_IsTrue( item );
|
||||
Py_DECREF(item);
|
||||
|
||||
if (param_arr[i] < 0) {
|
||||
if(data==NULL)
|
||||
MEM_freeN(param_arr);
|
||||
PyErr_Format(PyExc_AttributeError, "%.200s one or more of the values in the sequence is not a boolean", error_prefix);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
if(data==NULL) {
|
||||
RNA_property_boolean_set_array(ptr, prop, param_arr);
|
||||
MEM_freeN(param_arr);
|
||||
}
|
||||
|
||||
ok= pyrna_py_to_boolean_array(value, ptr, prop, data, error_str, sizeof(error_str));
|
||||
break;
|
||||
}
|
||||
case PROP_INT:
|
||||
{
|
||||
int *param_arr;
|
||||
if(data) param_arr= (int*)data;
|
||||
else param_arr= MEM_mallocN(sizeof(int) * len, "pyrna int array");
|
||||
|
||||
|
||||
/* collect the variables */
|
||||
for (i=0; i<len; i++) {
|
||||
item = PySequence_GetItem(value, i);
|
||||
param_arr[i] = (int)PyLong_AsSsize_t(item); /* deal with any errors later */
|
||||
Py_DECREF(item);
|
||||
}
|
||||
|
||||
if (PyErr_Occurred()) {
|
||||
if(data==NULL)
|
||||
MEM_freeN(param_arr);
|
||||
PyErr_Format(PyExc_AttributeError, "%.200s one or more of the values in the sequence could not be used as an int", error_prefix);
|
||||
return -1;
|
||||
}
|
||||
if(data==NULL) {
|
||||
RNA_property_int_set_array(ptr, prop, param_arr);
|
||||
MEM_freeN(param_arr);
|
||||
}
|
||||
ok= pyrna_py_to_int_array(value, ptr, prop, data, error_str, sizeof(error_str));
|
||||
break;
|
||||
}
|
||||
case PROP_FLOAT:
|
||||
{
|
||||
float *param_arr;
|
||||
if(data) param_arr = (float*)data;
|
||||
else param_arr = MEM_mallocN(sizeof(float) * len, "pyrna float array");
|
||||
|
||||
|
||||
#ifdef USE_MATHUTILS
|
||||
if(MatrixObject_Check(value) && RNA_property_subtype(prop) == PROP_MATRIX) {
|
||||
MatrixObject *mat = (MatrixObject*)value;
|
||||
memcpy(param_arr, mat->contigPtr, sizeof(float) * len);
|
||||
} else /* continue... */
|
||||
#endif
|
||||
{
|
||||
/* collect the variables */
|
||||
for (i=0; i<len; i++) {
|
||||
item = PySequence_GetItem(value, i);
|
||||
param_arr[i] = (float)PyFloat_AsDouble(item); /* deal with any errors later */
|
||||
Py_DECREF(item);
|
||||
}
|
||||
}
|
||||
|
||||
if (PyErr_Occurred()) {
|
||||
if(data==NULL)
|
||||
MEM_freeN(param_arr);
|
||||
PyErr_Format(PyExc_AttributeError, "%.200s one or more of the values in the sequence could not be used as a float", error_prefix);
|
||||
return -1;
|
||||
}
|
||||
if(data==NULL) {
|
||||
RNA_property_float_set_array(ptr, prop, param_arr);
|
||||
MEM_freeN(param_arr);
|
||||
}
|
||||
ok= pyrna_py_to_float_array(value, ptr, prop, data, error_str, sizeof(error_str));
|
||||
break;
|
||||
}
|
||||
if (!ok) {
|
||||
PyErr_Format(PyExc_AttributeError, "%.200s %s", error_prefix, error_str);
|
||||
return -1;
|
||||
}
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
/* Normal Property (not an array) */
|
||||
|
||||
/* see if we can coorce into a python type - PropertyType */
|
||||
@@ -862,7 +777,7 @@ 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->prop);
|
||||
len = RNA_property_array_length(&self->ptr, self->prop);
|
||||
|
||||
if (len==0) { /* not an array*/
|
||||
PyErr_SetString(PyExc_AttributeError, "len() only available for collection RNA types");
|
||||
@@ -888,7 +803,7 @@ static PyObject *prop_subscript_collection_int(BPy_PropertyRNA * self, int keynu
|
||||
}
|
||||
static PyObject *prop_subscript_array_int(BPy_PropertyRNA * self, int keynum)
|
||||
{
|
||||
int len= RNA_property_array_length(self->prop);
|
||||
int len= RNA_property_array_length(&self->ptr, self->prop);
|
||||
|
||||
if(keynum < 0) keynum += len;
|
||||
|
||||
@@ -993,7 +908,7 @@ 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->prop);
|
||||
int len= RNA_property_array_length(&self->ptr, self->prop);
|
||||
Py_ssize_t start, stop, step, slicelength;
|
||||
|
||||
if (PySlice_GetIndicesEx((PySliceObject*)key, len, &start, &stop, &step, &slicelength) < 0)
|
||||
@@ -1020,7 +935,7 @@ 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->prop)) { /* arrays are currently fixed length, zero length means its not an array */
|
||||
} else if (RNA_property_array_length(&self->ptr, self->prop)) { /* arrays are currently fixed length, 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");
|
||||
@@ -1049,7 +964,7 @@ 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->prop);
|
||||
int len= RNA_property_array_length(&self->ptr, self->prop);
|
||||
|
||||
if(keynum < 0) keynum += len;
|
||||
|
||||
@@ -1083,7 +998,7 @@ static int pyrna_prop_ass_subscript( BPy_PropertyRNA * self, PyObject *key, PyOb
|
||||
return prop_subscript_ass_array_int(self, i, value);
|
||||
}
|
||||
else if (PySlice_Check(key)) {
|
||||
int len= RNA_property_array_length(self->prop);
|
||||
int len= RNA_property_array_length(&self->ptr, self->prop);
|
||||
Py_ssize_t start, stop, step, slicelength;
|
||||
|
||||
if (PySlice_GetIndicesEx((PySliceObject*)key, len, &start, &stop, &step, &slicelength) < 0)
|
||||
@@ -1496,7 +1411,7 @@ static void foreach_attr_type( BPy_PropertyRNA *self, char *attr,
|
||||
RNA_PROP_BEGIN(&self->ptr, itemptr, self->prop) {
|
||||
prop = RNA_struct_find_property(&itemptr, attr);
|
||||
*raw_type= RNA_property_raw_type(prop);
|
||||
*attr_tot = RNA_property_array_length(prop);
|
||||
*attr_tot = RNA_property_array_length(&itemptr, prop);
|
||||
*attr_signed= (RNA_property_subtype(prop)==PROP_UNSIGNED) ? FALSE:TRUE;
|
||||
break;
|
||||
}
|
||||
@@ -1535,7 +1450,7 @@ static int foreach_parse_args(
|
||||
if (RNA_property_type(self->prop) == PROP_COLLECTION)
|
||||
array_tot = RNA_property_collection_length(&self->ptr, self->prop);
|
||||
else
|
||||
array_tot = RNA_property_array_length(self->prop);
|
||||
array_tot = RNA_property_array_length(&self->ptr, self->prop);
|
||||
|
||||
|
||||
target_tot= array_tot * (*attr_tot);
|
||||
@@ -1728,7 +1643,7 @@ PyObject *pyrna_prop_iter(BPy_PropertyRNA *self)
|
||||
|
||||
if (ret==NULL) {
|
||||
/* collection did not work, try array */
|
||||
int len = RNA_property_array_length(self->prop);
|
||||
int len = RNA_property_array_length(&self->ptr, self->prop);
|
||||
|
||||
if (len) {
|
||||
int i;
|
||||
@@ -1819,7 +1734,7 @@ PyObject *pyrna_param_to_py(PointerRNA *ptr, PropertyRNA *prop, void *data)
|
||||
{
|
||||
PyObject *ret;
|
||||
int type = RNA_property_type(prop);
|
||||
int len = RNA_property_array_length(prop);
|
||||
int len = RNA_property_array_length(ptr, prop);
|
||||
|
||||
int a;
|
||||
|
||||
|
||||
@@ -91,4 +91,9 @@ PyObject *pyrna_basetype_unregister(PyObject *self, PyObject *args);
|
||||
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);
|
||||
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user