2 * ***** BEGIN GPL LICENSE BLOCK *****
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version 2
7 * of the License, or (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software Foundation,
16 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18 * Contributor(s): Blender Foundation (2008).
20 * ***** END GPL LICENSE BLOCK *****
23 /** \file blender/makesrna/intern/rna_access.c
33 #include "MEM_guardedalloc.h"
36 #include "DNA_scene_types.h"
37 #include "DNA_windowmanager_types.h"
39 #include "BLI_blenlib.h"
40 #include "BLI_utildefines.h"
41 #include "BLI_dynstr.h"
42 #include "BLI_ghash.h"
46 #include "BLF_translation.h"
48 #include "BKE_animsys.h"
49 #include "BKE_context.h"
50 #include "BKE_idcode.h"
51 #include "BKE_idprop.h"
52 #include "BKE_fcurve.h"
54 #include "BKE_report.h"
56 #include "RNA_access.h"
57 #include "RNA_define.h"
62 #include "DNA_object_types.h"
63 #include "BKE_depsgraph.h"
66 #include "rna_internal.h"
68 const PointerRNA PointerRNA_NULL = {{NULL}};
77 for (srna = BLENDER_RNA.structs.first; srna; srna = srna->cont.next) {
78 if (!srna->cont.prophash) {
79 srna->cont.prophash = BLI_ghash_str_new("RNA_init gh");
81 for (prop = srna->cont.properties.first; prop; prop = prop->next)
82 if (!(prop->flag & PROP_BUILTIN))
83 BLI_ghash_insert(srna->cont.prophash, (void *)prop->identifier, prop);
92 RNA_property_update_cache_free();
94 for (srna = BLENDER_RNA.structs.first; srna; srna = srna->cont.next) {
95 if (srna->cont.prophash) {
96 BLI_ghash_free(srna->cont.prophash, NULL, NULL);
97 srna->cont.prophash = NULL;
101 RNA_free(&BLENDER_RNA);
106 void RNA_main_pointer_create(struct Main *main, PointerRNA *r_ptr)
108 r_ptr->id.data = NULL;
109 r_ptr->type = &RNA_BlendData;
113 void RNA_id_pointer_create(ID *id, PointerRNA *r_ptr)
115 StructRNA *type, *idtype = NULL;
118 PointerRNA tmp = {{NULL}};
120 idtype = rna_ID_refine(&tmp);
122 while (idtype->refine) {
123 type = idtype->refine(&tmp);
133 r_ptr->type = idtype;
137 void RNA_pointer_create(ID *id, StructRNA *type, void *data, PointerRNA *r_ptr)
140 StructRNA *idtype = NULL;
143 PointerRNA tmp = {{0}};
145 idtype = rna_ID_refine(&tmp);
154 while (r_ptr->type && r_ptr->type->refine) {
155 StructRNA *rtype = r_ptr->type->refine(r_ptr);
157 if (rtype == r_ptr->type)
165 static void rna_pointer_inherit_id(StructRNA *type, PointerRNA *parent, PointerRNA *ptr)
167 if (type && type->flag & STRUCT_ID) {
168 ptr->id.data = ptr->data;
171 ptr->id.data = parent->id.data;
175 void RNA_blender_rna_pointer_create(PointerRNA *r_ptr)
177 r_ptr->id.data = NULL;
178 r_ptr->type = &RNA_BlenderRNA;
179 r_ptr->data = &BLENDER_RNA;
182 PointerRNA rna_pointer_inherit_refine(PointerRNA *ptr, StructRNA *type, void *data)
188 rna_pointer_inherit_id(type, ptr, &result);
190 while (result.type->refine) {
191 type = result.type->refine(&result);
193 if (type == result.type)
201 return PointerRNA_NULL;
206 void RNA_pointer_recast(PointerRNA *ptr, PointerRNA *r_ptr)
208 #if 0 /* works but this case if covered by more general code below. */
209 if (RNA_struct_is_ID(ptr->type)) {
211 RNA_id_pointer_create(ptr->id.data, r_ptr);
218 *r_ptr = *ptr; /* initialize as the same in case cant recast */
220 for (base = ptr->type->base; base; base = base->base) {
221 t_ptr = rna_pointer_inherit_refine(ptr, base, ptr->data);
222 if (t_ptr.type && t_ptr.type != ptr->type) {
231 static void rna_idproperty_touch(IDProperty *idprop)
233 /* so the property is seen as 'set' by rna */
234 idprop->flag &= ~IDP_FLAG_GHOST;
237 /* return a UI local ID prop definition for this prop */
238 static IDProperty *rna_idproperty_ui(PropertyRNA *prop)
242 for (idprop = ((IDProperty *)prop)->prev; idprop; idprop = idprop->prev) {
243 if (strcmp(RNA_IDP_UI, idprop->name) == 0)
247 if (idprop == NULL) {
248 for (idprop = ((IDProperty *)prop)->next; idprop; idprop = idprop->next) {
249 if (strcmp(RNA_IDP_UI, idprop->name) == 0)
255 return IDP_GetPropertyTypeFromGroup(idprop, ((IDProperty *)prop)->name, IDP_GROUP);
261 IDProperty *RNA_struct_idprops(PointerRNA *ptr, bool create)
263 StructRNA *type = ptr->type;
265 if (type && type->idproperties)
266 return type->idproperties(ptr, create);
271 bool RNA_struct_idprops_check(StructRNA *srna)
273 return (srna && srna->idproperties);
276 static IDProperty *rna_idproperty_find(PointerRNA *ptr, const char *name)
278 IDProperty *group = RNA_struct_idprops(ptr, 0);
281 return IDP_GetPropertyFromGroup(group, name);
286 static void rna_idproperty_free(PointerRNA *ptr, const char *name)
288 IDProperty *group = RNA_struct_idprops(ptr, 0);
291 IDProperty *idprop = IDP_GetPropertyFromGroup(group, name);
293 IDP_FreeFromGroup(group, idprop);
298 static int rna_ensure_property_array_length(PointerRNA *ptr, PropertyRNA *prop)
300 if (prop->magic == RNA_MAGIC) {
301 int arraylen[RNA_MAX_ARRAY_DIMENSION];
302 return (prop->getlength && ptr->data) ? prop->getlength(ptr, arraylen) : prop->totarraylength;
305 IDProperty *idprop = (IDProperty *)prop;
307 if (idprop->type == IDP_ARRAY)
314 static bool rna_ensure_property_array_check(PropertyRNA *prop)
316 if (prop->magic == RNA_MAGIC) {
317 return (prop->getlength || prop->totarraylength);
320 IDProperty *idprop = (IDProperty *)prop;
322 return (idprop->type == IDP_ARRAY);
326 static void rna_ensure_property_multi_array_length(PointerRNA *ptr, PropertyRNA *prop, int length[])
328 if (prop->magic == RNA_MAGIC) {
330 prop->getlength(ptr, length);
332 memcpy(length, prop->arraylength, prop->arraydimension * sizeof(int));
335 IDProperty *idprop = (IDProperty *)prop;
337 if (idprop->type == IDP_ARRAY)
338 length[0] = idprop->len;
344 static bool rna_idproperty_verify_valid(PointerRNA *ptr, PropertyRNA *prop, IDProperty *idprop)
346 /* this verifies if the idproperty actually matches the property
347 * description and otherwise removes it. this is to ensure that
348 * rna property access is type safe, e.g. if you defined the rna
349 * to have a certain array length you can count on that staying so */
351 switch (idprop->type) {
353 if (prop->type != PROP_COLLECTION)
357 if (rna_ensure_property_array_length(ptr, prop) != idprop->len)
360 if (idprop->subtype == IDP_FLOAT && prop->type != PROP_FLOAT)
362 if (idprop->subtype == IDP_INT && !ELEM3(prop->type, PROP_BOOLEAN, PROP_INT, PROP_ENUM))
367 if (!ELEM3(prop->type, PROP_BOOLEAN, PROP_INT, PROP_ENUM))
372 if (prop->type != PROP_FLOAT)
376 if (prop->type != PROP_STRING)
380 if (prop->type != PROP_POINTER)
390 static PropertyRNA *typemap[IDP_NUMTYPES] = {
391 (PropertyRNA *)&rna_PropertyGroupItem_string,
392 (PropertyRNA *)&rna_PropertyGroupItem_int,
393 (PropertyRNA *)&rna_PropertyGroupItem_float,
395 (PropertyRNA *)&rna_PropertyGroupItem_group, NULL,
396 (PropertyRNA *)&rna_PropertyGroupItem_double,
397 (PropertyRNA *)&rna_PropertyGroupItem_idp_array
400 static PropertyRNA *arraytypemap[IDP_NUMTYPES] = {
401 NULL, (PropertyRNA *)&rna_PropertyGroupItem_int_array,
402 (PropertyRNA *)&rna_PropertyGroupItem_float_array,
404 (PropertyRNA *)&rna_PropertyGroupItem_collection, NULL,
405 (PropertyRNA *)&rna_PropertyGroupItem_double_array
408 IDProperty *rna_idproperty_check(PropertyRNA **prop, PointerRNA *ptr)
410 /* This is quite a hack, but avoids some complexity in the API. we
411 * pass IDProperty structs as PropertyRNA pointers to the outside.
412 * We store some bytes in PropertyRNA structs that allows us to
413 * distinguish it from IDProperty structs. If it is an ID property,
414 * we look up an IDP PropertyRNA based on the type, and set the data
415 * pointer to the IDProperty. */
417 if ((*prop)->magic == RNA_MAGIC) {
418 if ((*prop)->flag & PROP_IDPROPERTY) {
419 IDProperty *idprop = rna_idproperty_find(ptr, (*prop)->identifier);
421 if (idprop && !rna_idproperty_verify_valid(ptr, *prop, idprop)) {
422 IDProperty *group = RNA_struct_idprops(ptr, 0);
424 IDP_FreeFromGroup(group, idprop);
435 IDProperty *idprop = (IDProperty *)(*prop);
437 if (idprop->type == IDP_ARRAY)
438 *prop = arraytypemap[(int)(idprop->subtype)];
440 *prop = typemap[(int)(idprop->type)];
446 static PropertyRNA *rna_ensure_property(PropertyRNA *prop)
448 /* the quick version if we don't need the idproperty */
450 if (prop->magic == RNA_MAGIC)
454 IDProperty *idprop = (IDProperty *)prop;
456 if (idprop->type == IDP_ARRAY)
457 return arraytypemap[(int)(idprop->subtype)];
459 return typemap[(int)(idprop->type)];
463 static const char *rna_ensure_property_identifier(PropertyRNA *prop)
465 if (prop->magic == RNA_MAGIC)
466 return prop->identifier;
468 return ((IDProperty *)prop)->name;
471 static const char *rna_ensure_property_description(PropertyRNA *prop)
473 const char *description = NULL;
475 if (prop->magic == RNA_MAGIC)
476 description = prop->description;
478 /* attempt to get the local ID values */
479 IDProperty *idp_ui = rna_idproperty_ui(prop);
482 IDProperty *item = IDP_GetPropertyTypeFromGroup(idp_ui, "description", IDP_STRING);
484 description = IDP_String(item);
487 if (description == NULL)
488 description = ((IDProperty *)prop)->name; /* XXX - not correct */
494 static const char *rna_ensure_property_name(PropertyRNA *prop)
498 if (prop->magic == RNA_MAGIC)
501 name = ((IDProperty *)prop)->name;
508 StructRNA *RNA_struct_find(const char *identifier)
512 for (type = BLENDER_RNA.structs.first; type; type = type->cont.next)
513 if (strcmp(type->identifier, identifier) == 0)
519 const char *RNA_struct_identifier(StructRNA *type)
521 return type->identifier;
524 const char *RNA_struct_ui_name(StructRNA *type)
526 return CTX_IFACE_(type->translation_context, type->name);
529 const char *RNA_struct_ui_name_raw(StructRNA *type)
534 int RNA_struct_ui_icon(StructRNA *type)
542 const char *RNA_struct_ui_description(StructRNA *type)
544 return TIP_(type->description);
547 const char *RNA_struct_ui_description_raw(StructRNA *type)
549 return type->description;
552 const char *RNA_struct_translation_context(StructRNA *type)
554 return type->translation_context;
557 PropertyRNA *RNA_struct_name_property(StructRNA *type)
559 return type->nameproperty;
562 PropertyRNA *RNA_struct_iterator_property(StructRNA *type)
564 return type->iteratorproperty;
567 StructRNA *RNA_struct_base(StructRNA *type)
572 bool RNA_struct_is_ID(StructRNA *type)
574 return (type->flag & STRUCT_ID) != 0;
577 bool RNA_struct_undo_check(StructRNA *type)
579 return (type->flag & STRUCT_UNDO) != 0;
582 bool RNA_struct_idprops_register_check(StructRNA *type)
584 return (type->flag & STRUCT_NO_IDPROPERTIES) == 0;
587 /* remove an id-property */
588 bool RNA_struct_idprops_unset(PointerRNA *ptr, const char *identifier)
590 IDProperty *group = RNA_struct_idprops(ptr, 0);
593 IDProperty *idp = IDP_GetPropertyFromGroup(group, identifier);
595 IDP_FreeFromGroup(group, idp);
603 bool RNA_struct_is_a(StructRNA *type, StructRNA *srna)
607 if (srna == &RNA_AnyType)
613 /* ptr->type is always maximally refined */
614 for (base = type; base; base = base->base)
621 PropertyRNA *RNA_struct_find_property(PointerRNA *ptr, const char *identifier)
623 if (identifier[0] == '[' && identifier[1] == '"') { /* " (dummy comment to avoid confusing some
624 * function lists in text editors) */
625 /* id prop lookup, not so common */
626 PropertyRNA *r_prop = NULL;
627 PointerRNA r_ptr; /* only support single level props */
628 if (RNA_path_resolve(ptr, identifier, &r_ptr, &r_prop) && (r_ptr.type == ptr->type) && (r_ptr.data == ptr->data))
632 /* most common case */
633 PropertyRNA *iterprop = RNA_struct_iterator_property(ptr->type);
636 if (RNA_property_collection_lookup_string(ptr, iterprop, identifier, &propptr))
643 /* Find the property which uses the given nested struct */
644 static PropertyRNA *RNA_struct_find_nested(PointerRNA *ptr, StructRNA *srna)
646 PropertyRNA *prop = NULL;
648 RNA_STRUCT_BEGIN (ptr, iprop)
650 /* This assumes that there can only be one user of this nested struct */
651 if (RNA_property_pointer_type(ptr, iprop) == srna) {
661 bool RNA_struct_contains_property(PointerRNA *ptr, PropertyRNA *prop_test)
663 /* note, prop_test could be freed memory, only use for comparison */
665 /* validate the RNA is ok */
666 PropertyRNA *iterprop;
669 iterprop = RNA_struct_iterator_property(ptr->type);
671 RNA_PROP_BEGIN (ptr, itemptr, iterprop)
673 /* PropertyRNA *prop = itemptr.data; */
674 if (prop_test == (PropertyRNA *)itemptr.data) {
684 /* low level direct access to type->properties, note this ignores parent classes so should be used with care */
685 const struct ListBase *RNA_struct_type_properties(StructRNA *srna)
687 return &srna->cont.properties;
690 PropertyRNA *RNA_struct_type_find_property(StructRNA *srna, const char *identifier)
692 return BLI_findstring_ptr(&srna->cont.properties, identifier, offsetof(PropertyRNA, identifier));
695 FunctionRNA *RNA_struct_find_function(StructRNA *srna, const char *identifier)
700 for (type = srna; type; type = type->base) {
701 func = (FunctionRNA *)BLI_findstring_ptr(&type->functions, identifier, offsetof(FunctionRNA, identifier));
708 /* funcitonal but slow */
711 PropertyRNA *iterprop;
714 RNA_pointer_create(NULL, &RNA_Struct, srna, &tptr);
715 iterprop = RNA_struct_find_property(&tptr, "functions");
719 RNA_PROP_BEGIN (&tptr, funcptr, iterprop)
721 if (strcmp(identifier, RNA_function_identifier(funcptr.data)) == 0) {
732 const ListBase *RNA_struct_type_functions(StructRNA *srna)
734 return &srna->functions;
737 StructRegisterFunc RNA_struct_register(StructRNA *type)
742 StructUnregisterFunc RNA_struct_unregister(StructRNA *type)
747 } while ((type = type->base));
752 void **RNA_struct_instance(PointerRNA *ptr)
754 StructRNA *type = ptr->type;
758 return type->instance(ptr);
759 } while ((type = type->base));
764 void *RNA_struct_py_type_get(StructRNA *srna)
766 return srna->py_type;
769 void RNA_struct_py_type_set(StructRNA *srna, void *py_type)
771 srna->py_type = py_type;
774 void *RNA_struct_blender_type_get(StructRNA *srna)
776 return srna->blender_type;
779 void RNA_struct_blender_type_set(StructRNA *srna, void *blender_type)
781 srna->blender_type = blender_type;
784 char *RNA_struct_name_get_alloc(PointerRNA *ptr, char *fixedbuf, int fixedlen, int *r_len)
786 PropertyRNA *nameprop;
788 if (ptr->data && (nameprop = RNA_struct_name_property(ptr->type)))
789 return RNA_property_string_get_alloc(ptr, nameprop, fixedbuf, fixedlen, r_len);
794 /* Property Information */
796 const char *RNA_property_identifier(PropertyRNA *prop)
798 return rna_ensure_property_identifier(prop);
801 const char *RNA_property_description(PropertyRNA *prop)
803 return TIP_(rna_ensure_property_description(prop));
806 PropertyType RNA_property_type(PropertyRNA *prop)
808 return rna_ensure_property(prop)->type;
811 PropertySubType RNA_property_subtype(PropertyRNA *prop)
813 return rna_ensure_property(prop)->subtype;
816 PropertyUnit RNA_property_unit(PropertyRNA *prop)
818 return RNA_SUBTYPE_UNIT(rna_ensure_property(prop)->subtype);
821 int RNA_property_flag(PropertyRNA *prop)
823 return rna_ensure_property(prop)->flag;
826 void *RNA_property_py_data_get(PropertyRNA *prop)
828 return prop->py_data;
831 int RNA_property_array_length(PointerRNA *ptr, PropertyRNA *prop)
833 return rna_ensure_property_array_length(ptr, prop);
836 bool RNA_property_array_check(PropertyRNA *prop)
838 return rna_ensure_property_array_check(prop);
841 /* used by BPY to make an array from the python object */
842 int RNA_property_array_dimension(PointerRNA *ptr, PropertyRNA *prop, int length[])
844 PropertyRNA *rprop = rna_ensure_property(prop);
847 rna_ensure_property_multi_array_length(ptr, prop, length);
849 return rprop->arraydimension;
852 /* Return the size of Nth dimension. */
853 int RNA_property_multi_array_length(PointerRNA *ptr, PropertyRNA *prop, int dim)
855 int len[RNA_MAX_ARRAY_DIMENSION];
857 rna_ensure_property_multi_array_length(ptr, prop, len);
862 char RNA_property_array_item_char(PropertyRNA *prop, int index)
864 const char *vectoritem = "XYZW";
865 const char *quatitem = "WXYZ";
866 const char *coloritem = "RGBA";
867 PropertySubType subtype = rna_ensure_property(prop)->subtype;
869 BLI_assert(index >= 0);
871 /* get string to use for array index */
872 if ((index < 4) && ELEM(subtype, PROP_QUATERNION, PROP_AXISANGLE)) {
873 return quatitem[index];
875 else if ((index < 4) && ELEM8(subtype, PROP_TRANSLATION, PROP_DIRECTION, PROP_XYZ, PROP_XYZ_LENGTH,
876 PROP_EULER, PROP_VELOCITY, PROP_ACCELERATION, PROP_COORDS))
878 return vectoritem[index];
880 else if ((index < 4) && ELEM(subtype, PROP_COLOR, PROP_COLOR_GAMMA)) {
881 return coloritem[index];
887 int RNA_property_array_item_index(PropertyRNA *prop, char name)
889 PropertySubType subtype = rna_ensure_property(prop)->subtype;
891 /* get index based on string name/alias */
892 /* maybe a function to find char index in string would be better than all the switches */
893 if (ELEM(subtype, PROP_QUATERNION, PROP_AXISANGLE)) {
905 else if (ELEM6(subtype, PROP_TRANSLATION, PROP_DIRECTION, PROP_XYZ,
906 PROP_EULER, PROP_VELOCITY, PROP_ACCELERATION))
919 else if (ELEM(subtype, PROP_COLOR, PROP_COLOR_GAMMA)) {
936 void RNA_property_int_range(PointerRNA *ptr, PropertyRNA *prop, int *hardmin, int *hardmax)
938 IntPropertyRNA *iprop = (IntPropertyRNA *)rna_ensure_property(prop);
939 int softmin, softmax;
941 if (prop->magic != RNA_MAGIC) {
942 /* attempt to get the local ID values */
943 IDProperty *idp_ui = rna_idproperty_ui(prop);
948 item = IDP_GetPropertyTypeFromGroup(idp_ui, "min", IDP_INT);
949 *hardmin = item ? IDP_Int(item) : INT_MIN;
951 item = IDP_GetPropertyTypeFromGroup(idp_ui, "max", IDP_INT);
952 *hardmax = item ? IDP_Int(item) : INT_MAX;
962 iprop->range(ptr, hardmin, hardmax, &softmin, &softmax);
964 else if (iprop->range_ex) {
968 iprop->range_ex(ptr, prop, hardmin, hardmax, &softmin, &softmax);
971 *hardmin = iprop->hardmin;
972 *hardmax = iprop->hardmax;
976 void RNA_property_int_ui_range(PointerRNA *ptr, PropertyRNA *prop, int *softmin, int *softmax, int *step)
978 IntPropertyRNA *iprop = (IntPropertyRNA *)rna_ensure_property(prop);
979 int hardmin, hardmax;
981 if (prop->magic != RNA_MAGIC) {
982 /* attempt to get the local ID values */
983 IDProperty *idp_ui = rna_idproperty_ui(prop);
988 item = IDP_GetPropertyTypeFromGroup(idp_ui, "soft_min", IDP_INT);
989 *softmin = item ? IDP_Int(item) : INT_MIN;
991 item = IDP_GetPropertyTypeFromGroup(idp_ui, "soft_max", IDP_INT);
992 *softmax = item ? IDP_Int(item) : INT_MAX;
994 item = IDP_GetPropertyTypeFromGroup(idp_ui, "step", IDP_INT);
995 *step = item ? IDP_Int(item) : 1;
1001 *softmin = iprop->softmin;
1002 *softmax = iprop->softmax;
1008 iprop->range(ptr, &hardmin, &hardmax, softmin, softmax);
1010 *softmin = max_ii(*softmin, hardmin);
1011 *softmax = min_ii(*softmax, hardmax);
1013 else if (iprop->range_ex) {
1017 iprop->range_ex(ptr, prop, &hardmin, &hardmax, softmin, softmax);
1019 *softmin = max_ii(*softmin, hardmin);
1020 *softmax = min_ii(*softmax, hardmax);
1023 *step = iprop->step;
1026 void RNA_property_float_range(PointerRNA *ptr, PropertyRNA *prop, float *hardmin, float *hardmax)
1028 FloatPropertyRNA *fprop = (FloatPropertyRNA *)rna_ensure_property(prop);
1029 float softmin, softmax;
1031 if (prop->magic != RNA_MAGIC) {
1032 /* attempt to get the local ID values */
1033 IDProperty *idp_ui = rna_idproperty_ui(prop);
1038 item = IDP_GetPropertyTypeFromGroup(idp_ui, "min", IDP_DOUBLE);
1039 *hardmin = item ? (float)IDP_Double(item) : -FLT_MAX;
1041 item = IDP_GetPropertyTypeFromGroup(idp_ui, "max", IDP_DOUBLE);
1042 *hardmax = item ? (float)IDP_Double(item) : FLT_MAX;
1049 *hardmin = -FLT_MAX;
1052 fprop->range(ptr, hardmin, hardmax, &softmin, &softmax);
1054 else if (fprop->range_ex) {
1055 *hardmin = -FLT_MAX;
1058 fprop->range_ex(ptr, prop, hardmin, hardmax, &softmin, &softmax);
1061 *hardmin = fprop->hardmin;
1062 *hardmax = fprop->hardmax;
1066 void RNA_property_float_ui_range(PointerRNA *ptr, PropertyRNA *prop, float *softmin, float *softmax,
1067 float *step, float *precision)
1069 FloatPropertyRNA *fprop = (FloatPropertyRNA *)rna_ensure_property(prop);
1070 float hardmin, hardmax;
1072 if (prop->magic != RNA_MAGIC) {
1073 /* attempt to get the local ID values */
1074 IDProperty *idp_ui = rna_idproperty_ui(prop);
1079 item = IDP_GetPropertyTypeFromGroup(idp_ui, "soft_min", IDP_DOUBLE);
1080 *softmin = item ? (float)IDP_Double(item) : -FLT_MAX;
1082 item = IDP_GetPropertyTypeFromGroup(idp_ui, "soft_max", IDP_DOUBLE);
1083 *softmax = item ? (float)IDP_Double(item) : FLT_MAX;
1085 item = IDP_GetPropertyTypeFromGroup(idp_ui, "step", IDP_DOUBLE);
1086 *step = item ? (float)IDP_Double(item) : 1.0f;
1088 item = IDP_GetPropertyTypeFromGroup(idp_ui, "precision", IDP_DOUBLE);
1089 *precision = item ? (float)IDP_Double(item) : 3.0f;
1095 *softmin = fprop->softmin;
1096 *softmax = fprop->softmax;
1102 fprop->range(ptr, &hardmin, &hardmax, softmin, softmax);
1104 *softmin = max_ff(*softmin, hardmin);
1105 *softmax = min_ff(*softmax, hardmax);
1107 else if (fprop->range_ex) {
1111 fprop->range_ex(ptr, prop, &hardmin, &hardmax, softmin, softmax);
1113 *softmin = max_ff(*softmin, hardmin);
1114 *softmax = min_ff(*softmax, hardmax);
1117 *step = fprop->step;
1118 *precision = (float)fprop->precision;
1121 int RNA_property_float_clamp(PointerRNA *ptr, PropertyRNA *prop, float *value)
1125 RNA_property_float_range(ptr, prop, &min, &max);
1131 else if (*value > max) {
1140 int RNA_property_int_clamp(PointerRNA *ptr, PropertyRNA *prop, int *value)
1144 RNA_property_int_range(ptr, prop, &min, &max);
1150 else if (*value > max) {
1159 /* this is the max length including \0 terminator.
1160 * '0' used when their is no maximum */
1161 int RNA_property_string_maxlength(PropertyRNA *prop)
1163 StringPropertyRNA *sprop = (StringPropertyRNA *)rna_ensure_property(prop);
1164 return sprop->maxlength;
1167 StructRNA *RNA_property_pointer_type(PointerRNA *ptr, PropertyRNA *prop)
1169 prop = rna_ensure_property(prop);
1171 if (prop->type == PROP_POINTER) {
1172 PointerPropertyRNA *pprop = (PointerPropertyRNA *)prop;
1175 return pprop->typef(ptr);
1176 else if (pprop->type)
1179 else if (prop->type == PROP_COLLECTION) {
1180 CollectionPropertyRNA *cprop = (CollectionPropertyRNA *)prop;
1182 if (cprop->item_type)
1183 return cprop->item_type;
1185 /* ignore other types, RNA_struct_find_nested calls with unchecked props */
1187 return &RNA_UnknownType;
1190 int RNA_property_pointer_poll(PointerRNA *ptr, PropertyRNA *prop, PointerRNA *value)
1192 prop = rna_ensure_property(prop);
1194 if (prop->type == PROP_POINTER) {
1195 PointerPropertyRNA *pprop = (PointerPropertyRNA *)prop;
1197 return pprop->poll(ptr, *value);
1202 printf("%s %s: is not a pointer property.\n", __func__, prop->identifier);
1206 /* Reuse for dynamic types */
1207 EnumPropertyItem DummyRNA_NULL_items[] = {
1208 {0, NULL, 0, NULL, NULL}
1211 /* Reuse for dynamic types with default value */
1212 EnumPropertyItem DummyRNA_DEFAULT_items[] = {
1213 {0, "DEFAULT", 0, "Default", ""},
1214 {0, NULL, 0, NULL, NULL}
1217 void RNA_property_enum_items(bContext *C, PointerRNA *ptr, PropertyRNA *prop, EnumPropertyItem **r_item,
1218 int *r_totitem, bool *r_free)
1220 EnumPropertyRNA *eprop = (EnumPropertyRNA *)rna_ensure_property(prop);
1224 if (eprop->itemf && (C != NULL || (prop->flag & PROP_ENUM_NO_CONTEXT))) {
1225 EnumPropertyItem *item;
1227 if (prop->flag & PROP_ENUM_NO_CONTEXT)
1228 item = eprop->itemf(NULL, ptr, prop, r_free);
1230 item = eprop->itemf(C, ptr, prop, r_free);
1232 /* any callbacks returning NULL should be fixed */
1233 BLI_assert(item != NULL);
1237 for (tot = 0; item[tot].identifier; tot++) {
1246 *r_item = eprop->item;
1248 *r_totitem = eprop->totitem;
1252 void RNA_property_enum_items_gettexted(bContext *C, PointerRNA *ptr, PropertyRNA *prop,
1253 EnumPropertyItem **r_item, int *r_totitem, bool *r_free)
1255 RNA_property_enum_items(C, ptr, prop, r_item, r_totitem, r_free);
1257 #ifdef WITH_INTERNATIONAL
1258 if (!(prop->flag & PROP_ENUM_NO_TRANSLATE)) {
1261 /* Note: Only do those tests once, and then use BLF_pgettext. */
1262 bool do_iface = BLF_translate_iface();
1263 bool do_tooltip = BLF_translate_tooltips();
1264 EnumPropertyItem *nitem;
1266 if (!(do_iface || do_tooltip))
1273 EnumPropertyItem *item = *r_item;
1281 for (tot = 0; item[tot].identifier; tot++) {
1286 nitem = MEM_mallocN(sizeof(EnumPropertyItem) * (tot + 1), "enum_items_gettexted");
1287 memcpy(nitem, item, sizeof(EnumPropertyItem) * (tot + 1));
1292 for (i = 0; nitem[i].identifier; i++) {
1293 if (nitem[i].name && do_iface) {
1294 nitem[i].name = BLF_pgettext(prop->translation_context, nitem[i].name);
1296 if (nitem[i].description && do_tooltip) {
1297 nitem[i].description = BLF_pgettext(NULL, nitem[i].description);
1307 bool RNA_property_enum_value(bContext *C, PointerRNA *ptr, PropertyRNA *prop, const char *identifier, int *r_value)
1309 EnumPropertyItem *item;
1313 RNA_property_enum_items(C, ptr, prop, &item, NULL, &free);
1316 const int i = RNA_enum_from_identifier(item, identifier);
1318 *r_value = item[i].value;
1335 bool RNA_enum_identifier(EnumPropertyItem *item, const int value, const char **r_identifier)
1337 const int i = RNA_enum_from_value(item, value);
1339 *r_identifier = item[i].identifier;
1347 int RNA_enum_bitflag_identifiers(EnumPropertyItem *item, const int value, const char **r_identifier)
1350 for (; item->identifier; item++) {
1351 if (item->identifier[0] && item->value & value) {
1352 r_identifier[index++] = item->identifier;
1355 r_identifier[index] = NULL;
1359 bool RNA_enum_name(EnumPropertyItem *item, const int value, const char **r_name)
1361 const int i = RNA_enum_from_value(item, value);
1363 *r_name = item[i].name;
1371 bool RNA_enum_description(EnumPropertyItem *item, const int value, const char **r_description)
1373 const int i = RNA_enum_from_value(item, value);
1375 *r_description = item[i].description;
1383 int RNA_enum_from_identifier(EnumPropertyItem *item, const char *identifier)
1386 for (; item->identifier; item++, i++) {
1387 if (item->identifier[0] && STREQ(item->identifier, identifier)) {
1394 int RNA_enum_from_value(EnumPropertyItem *item, const int value)
1397 for (; item->identifier; item++, i++) {
1398 if (item->identifier[0] && item->value == value) {
1405 bool RNA_property_enum_identifier(bContext *C, PointerRNA *ptr, PropertyRNA *prop, const int value,
1406 const char **identifier)
1408 EnumPropertyItem *item = NULL;
1411 RNA_property_enum_items(C, ptr, prop, &item, NULL, &free);
1414 result = RNA_enum_identifier(item, value, identifier);
1423 bool RNA_property_enum_name(bContext *C, PointerRNA *ptr, PropertyRNA *prop, const int value, const char **name)
1425 EnumPropertyItem *item = NULL;
1428 RNA_property_enum_items(C, ptr, prop, &item, NULL, &free);
1431 result = RNA_enum_name(item, value, name);
1440 bool RNA_property_enum_name_gettexted(bContext *C, PointerRNA *ptr, PropertyRNA *prop, const int value, const char **name)
1444 result = RNA_property_enum_name(C, ptr, prop, value, name);
1447 if (!(prop->flag & PROP_ENUM_NO_TRANSLATE)) {
1448 if (BLF_translate_iface()) {
1449 *name = BLF_pgettext(prop->translation_context, *name);
1457 int RNA_property_enum_bitflag_identifiers(bContext *C, PointerRNA *ptr, PropertyRNA *prop, const int value,
1458 const char **identifier)
1460 EnumPropertyItem *item = NULL;
1463 RNA_property_enum_items(C, ptr, prop, &item, NULL, &free);
1466 result = RNA_enum_bitflag_identifiers(item, value, identifier);
1475 const char *RNA_property_ui_name(PropertyRNA *prop)
1477 return CTX_IFACE_(prop->translation_context, rna_ensure_property_name(prop));
1480 const char *RNA_property_ui_name_raw(PropertyRNA *prop)
1482 return rna_ensure_property_name(prop);
1485 const char *RNA_property_ui_description(PropertyRNA *prop)
1487 return TIP_(rna_ensure_property_description(prop));
1490 const char *RNA_property_ui_description_raw(PropertyRNA *prop)
1492 return rna_ensure_property_description(prop);
1495 const char *RNA_property_translation_context(PropertyRNA *_prop)
1497 PropertyRNA *prop = rna_ensure_property(_prop);
1498 return prop->translation_context;
1501 int RNA_property_ui_icon(PropertyRNA *prop)
1503 return rna_ensure_property(prop)->icon;
1506 bool RNA_property_editable(PointerRNA *ptr, PropertyRNA *prop)
1508 ID *id = ptr->id.data;
1511 prop = rna_ensure_property(prop);
1512 flag = prop->editable ? prop->editable(ptr) : prop->flag;
1513 return (flag & PROP_EDITABLE) && (!id || !id->lib || (prop->flag & PROP_LIB_EXCEPTION));
1516 bool RNA_property_editable_flag(PointerRNA *ptr, PropertyRNA *prop)
1520 prop = rna_ensure_property(prop);
1521 flag = prop->editable ? prop->editable(ptr) : prop->flag;
1522 return (flag & PROP_EDITABLE) != 0;
1525 /* same as RNA_property_editable(), except this checks individual items in an array */
1526 bool RNA_property_editable_index(PointerRNA *ptr, PropertyRNA *prop, int index)
1531 BLI_assert(index >= 0);
1533 prop = rna_ensure_property(prop);
1538 flag &= prop->editable(ptr);
1540 if (prop->itemeditable)
1541 flag &= prop->itemeditable(ptr, index);
1545 return (flag & PROP_EDITABLE) && (!id || !id->lib || (prop->flag & PROP_LIB_EXCEPTION));
1548 bool RNA_property_animateable(PointerRNA *ptr, PropertyRNA *prop)
1550 /* check that base ID-block can support animation data */
1551 if (!id_type_can_have_animdata(ptr->id.data))
1554 prop = rna_ensure_property(prop);
1556 if (!(prop->flag & PROP_ANIMATABLE))
1559 return (prop->flag & PROP_EDITABLE) != 0;
1562 bool RNA_property_animated(PointerRNA *ptr, PropertyRNA *prop)
1570 if (RNA_property_array_check(prop))
1571 len = RNA_property_array_length(ptr, prop);
1573 for (index = 0; index < len; index++)
1574 if (rna_get_fcurve(ptr, prop, index, NULL, &driven))
1580 /* this function is to check if its possible to create a valid path from the ID
1581 * its slow so don't call in a loop */
1582 bool RNA_property_path_from_ID_check(PointerRNA *ptr, PropertyRNA *prop)
1584 char *path = RNA_path_from_ID_to_property(ptr, prop);
1590 PropertyRNA *r_prop;
1592 RNA_id_pointer_create(ptr->id.data, &id_ptr);
1593 if (RNA_path_resolve(&id_ptr, path, &r_ptr, &r_prop) == true) {
1594 ret = (prop == r_prop);
1603 static void rna_property_update(bContext *C, Main *bmain, Scene *scene, PointerRNA *ptr, PropertyRNA *prop)
1605 const bool is_rna = (prop->magic == RNA_MAGIC);
1606 prop = rna_ensure_property(prop);
1610 /* ideally no context would be needed for update, but there's some
1611 * parts of the code that need it still, so we have this exception */
1612 if (prop->flag & PROP_CONTEXT_UPDATE) {
1614 if (prop->flag & PROP_CONTEXT_PROPERTY_UPDATE) {
1615 ((ContextPropUpdateFunc)prop->update)(C, ptr, prop);
1618 ((ContextUpdateFunc)prop->update)(C, ptr);
1623 prop->update(bmain, scene, ptr);
1626 WM_main_add_notifier(prop->noteflag, ptr->id.data);
1629 if (!is_rna || (prop->flag & PROP_IDPROPERTY)) {
1630 /* WARNING! This is so property drivers update the display!
1631 * not especially nice */
1632 DAG_id_tag_update(ptr->id.data, OB_RECALC_OB | OB_RECALC_DATA | OB_RECALC_TIME);
1633 WM_main_add_notifier(NC_WINDOW, NULL);
1637 /* must keep in sync with 'rna_property_update'
1638 * note, its possible this returns a false positive in the case of PROP_CONTEXT_UPDATE
1639 * but this isn't likely to be a performance problem. */
1640 bool RNA_property_update_check(PropertyRNA *prop)
1642 return (prop->magic != RNA_MAGIC || prop->update || prop->noteflag);
1645 void RNA_property_update(bContext *C, PointerRNA *ptr, PropertyRNA *prop)
1647 rna_property_update(C, CTX_data_main(C), CTX_data_scene(C), ptr, prop);
1650 void RNA_property_update_main(Main *bmain, Scene *scene, PointerRNA *ptr, PropertyRNA *prop)
1652 rna_property_update(NULL, bmain, scene, ptr, prop);
1656 /* RNA Updates Cache ------------------------ */
1657 /* Overview of RNA Update cache system:
1659 * RNA Update calls need to be cached in order to maintain reasonable performance
1660 * of the animation system (i.e. maintaining a somewhat interactive framerate)
1661 * while still allowing updates to be called (necessary in particular for modifier
1662 * property updates to actually work).
1664 * The cache is structured with a dual-layer structure
1665 * - L1 = PointerRNA used as key; id.data is used (it should always be defined,
1666 * and most updates end up using just that anyways)
1667 * - L2 = Update functions to be called on those PointerRNA's
1671 typedef struct tRnaUpdateCacheElem {
1672 struct tRnaUpdateCacheElem *next, *prev;
1674 PointerRNA ptr; /* L1 key - id as primary, data secondary/ignored? */
1675 ListBase L2Funcs; /* L2 functions (LinkData<RnaUpdateFuncRef>) */
1676 } tRnaUpdateCacheElem;
1678 /* cache global (tRnaUpdateCacheElem's) - only accessible using these API calls */
1679 static ListBase rna_updates_cache = {NULL, NULL};
1681 /* ........................... */
1683 void RNA_property_update_cache_add(PointerRNA *ptr, PropertyRNA *prop)
1685 const bool is_rna = (prop->magic == RNA_MAGIC);
1686 tRnaUpdateCacheElem *uce = NULL;
1687 UpdateFunc fn = NULL;
1694 prop = rna_ensure_property(prop);
1696 /* we can only handle update calls with no context args for now (makes animsys updates easier) */
1697 if ((is_rna == false) || (prop->update == NULL) || (prop->flag & PROP_CONTEXT_UPDATE))
1701 /* find cache element for which key matches... */
1702 for (uce = rna_updates_cache.first; uce; uce = uce->next) {
1703 /* just match by id only for now, since most update calls that we'll encounter only really care about this */
1704 /* TODO: later, the cache might need to have some nesting on L1 to cope better
1705 * with these problems + some tagging to indicate we need this */
1706 if (uce->ptr.id.data == ptr->id.data)
1710 /* create new instance */
1711 uce = MEM_callocN(sizeof(tRnaUpdateCacheElem), "tRnaUpdateCacheElem");
1712 BLI_addtail(&rna_updates_cache, uce);
1715 RNA_pointer_create(ptr->id.data, ptr->type, ptr->data, &uce->ptr);
1718 /* check on the update func */
1719 for (ld = uce->L2Funcs.first; ld; ld = ld->next) {
1720 /* stop on match - function already cached */
1724 /* else... if still here, we need to add it */
1725 BLI_addtail(&uce->L2Funcs, BLI_genericNodeN(fn));
1728 void RNA_property_update_cache_flush(Main *bmain, Scene *scene)
1730 tRnaUpdateCacheElem *uce;
1732 /* TODO: should we check that bmain and scene are valid? The above stuff doesn't! */
1734 /* execute the cached updates */
1735 for (uce = rna_updates_cache.first; uce; uce = uce->next) {
1738 for (ld = uce->L2Funcs.first; ld; ld = ld->next) {
1739 UpdateFunc fn = (UpdateFunc)ld->data;
1740 fn(bmain, scene, &uce->ptr);
1745 void RNA_property_update_cache_free(void)
1747 tRnaUpdateCacheElem *uce, *ucn;
1749 for (uce = rna_updates_cache.first; uce; uce = ucn) {
1753 BLI_freelistN(&uce->L2Funcs);
1756 BLI_freelinkN(&rna_updates_cache, uce);
1760 /* ---------------------------------------------------------------------- */
1764 int RNA_property_boolean_get(PointerRNA *ptr, PropertyRNA *prop)
1766 BoolPropertyRNA *bprop = (BoolPropertyRNA *)prop;
1769 BLI_assert(RNA_property_type(prop) == PROP_BOOLEAN);
1770 BLI_assert(RNA_property_array_check(prop) == false);
1772 if ((idprop = rna_idproperty_check(&prop, ptr)))
1773 return IDP_Int(idprop);
1774 else if (bprop->get)
1775 return bprop->get(ptr);
1776 else if (bprop->get_ex)
1777 return bprop->get_ex(ptr, prop);
1779 return bprop->defaultvalue;
1782 void RNA_property_boolean_set(PointerRNA *ptr, PropertyRNA *prop, int value)
1784 BoolPropertyRNA *bprop = (BoolPropertyRNA *)prop;
1787 BLI_assert(RNA_property_type(prop) == PROP_BOOLEAN);
1788 BLI_assert(RNA_property_array_check(prop) == false);
1790 /* just in case other values are passed */
1791 if (value) value = 1;
1793 if ((idprop = rna_idproperty_check(&prop, ptr))) {
1794 IDP_Int(idprop) = value;
1795 rna_idproperty_touch(idprop);
1797 else if (bprop->set) {
1798 bprop->set(ptr, value);
1800 else if (bprop->set_ex) {
1801 bprop->set_ex(ptr, prop, value);
1803 else if (prop->flag & PROP_EDITABLE) {
1804 IDPropertyTemplate val = {0};
1809 group = RNA_struct_idprops(ptr, 1);
1811 IDP_AddToGroup(group, IDP_New(IDP_INT, &val, prop->identifier));
1815 void RNA_property_boolean_get_array(PointerRNA *ptr, PropertyRNA *prop, int *values)
1817 BoolPropertyRNA *bprop = (BoolPropertyRNA *)prop;
1820 BLI_assert(RNA_property_type(prop) == PROP_BOOLEAN);
1821 BLI_assert(RNA_property_array_check(prop) != false);
1823 if ((idprop = rna_idproperty_check(&prop, ptr))) {
1824 if (prop->arraydimension == 0)
1825 values[0] = RNA_property_boolean_get(ptr, prop);
1827 memcpy(values, IDP_Array(idprop), sizeof(int) * idprop->len);
1829 else if (prop->arraydimension == 0)
1830 values[0] = RNA_property_boolean_get(ptr, prop);
1831 else if (bprop->getarray)
1832 bprop->getarray(ptr, values);
1833 else if (bprop->getarray_ex)
1834 bprop->getarray_ex(ptr, prop, values);
1835 else if (bprop->defaultarray)
1836 memcpy(values, bprop->defaultarray, sizeof(int) * prop->totarraylength);
1838 memset(values, 0, sizeof(int) * prop->totarraylength);
1841 int RNA_property_boolean_get_index(PointerRNA *ptr, PropertyRNA *prop, int index)
1843 int tmp[RNA_MAX_ARRAY_LENGTH];
1844 int len = rna_ensure_property_array_length(ptr, prop);
1846 BLI_assert(RNA_property_type(prop) == PROP_BOOLEAN);
1847 BLI_assert(RNA_property_array_check(prop) != false);
1848 BLI_assert(index >= 0);
1850 if (len <= RNA_MAX_ARRAY_LENGTH) {
1851 RNA_property_boolean_get_array(ptr, prop, tmp);
1855 int *tmparray, value;
1857 tmparray = MEM_callocN(sizeof(int) * len, "RNA_property_boolean_get_index");
1858 RNA_property_boolean_get_array(ptr, prop, tmparray);
1859 value = tmparray[index];
1860 MEM_freeN(tmparray);
1866 void RNA_property_boolean_set_array(PointerRNA *ptr, PropertyRNA *prop, const int *values)
1868 BoolPropertyRNA *bprop = (BoolPropertyRNA *)prop;
1871 BLI_assert(RNA_property_type(prop) == PROP_BOOLEAN);
1872 BLI_assert(RNA_property_array_check(prop) != false);
1874 if ((idprop = rna_idproperty_check(&prop, ptr))) {
1875 if (prop->arraydimension == 0)
1876 IDP_Int(idprop) = values[0];
1878 memcpy(IDP_Array(idprop), values, sizeof(int) * idprop->len);
1880 rna_idproperty_touch(idprop);
1882 else if (prop->arraydimension == 0)
1883 RNA_property_boolean_set(ptr, prop, values[0]);
1884 else if (bprop->setarray)
1885 bprop->setarray(ptr, values);
1886 else if (bprop->setarray_ex)
1887 bprop->setarray_ex(ptr, prop, values);
1888 else if (prop->flag & PROP_EDITABLE) {
1889 IDPropertyTemplate val = {0};
1892 val.array.len = prop->totarraylength;
1893 val.array.type = IDP_INT;
1895 group = RNA_struct_idprops(ptr, 1);
1897 idprop = IDP_New(IDP_ARRAY, &val, prop->identifier);
1898 IDP_AddToGroup(group, idprop);
1899 memcpy(IDP_Array(idprop), values, sizeof(int) * idprop->len);
1904 void RNA_property_boolean_set_index(PointerRNA *ptr, PropertyRNA *prop, int index, int value)
1906 int tmp[RNA_MAX_ARRAY_LENGTH];
1907 int len = rna_ensure_property_array_length(ptr, prop);
1909 BLI_assert(RNA_property_type(prop) == PROP_BOOLEAN);
1910 BLI_assert(RNA_property_array_check(prop) != false);
1911 BLI_assert(index >= 0);
1913 if (len <= RNA_MAX_ARRAY_LENGTH) {
1914 RNA_property_boolean_get_array(ptr, prop, tmp);
1916 RNA_property_boolean_set_array(ptr, prop, tmp);
1921 tmparray = MEM_callocN(sizeof(int) * len, "RNA_property_boolean_get_index");
1922 RNA_property_boolean_get_array(ptr, prop, tmparray);
1923 tmparray[index] = value;
1924 RNA_property_boolean_set_array(ptr, prop, tmparray);
1925 MEM_freeN(tmparray);
1929 int RNA_property_boolean_get_default(PointerRNA *UNUSED(ptr), PropertyRNA *prop)
1931 BoolPropertyRNA *bprop = (BoolPropertyRNA *)rna_ensure_property(prop);
1933 BLI_assert(RNA_property_type(prop) == PROP_BOOLEAN);
1934 BLI_assert(RNA_property_array_check(prop) == false);
1936 return bprop->defaultvalue;
1939 void RNA_property_boolean_get_default_array(PointerRNA *UNUSED(ptr), PropertyRNA *prop, int *values)
1941 BoolPropertyRNA *bprop = (BoolPropertyRNA *)rna_ensure_property(prop);
1943 BLI_assert(RNA_property_type(prop) == PROP_BOOLEAN);
1944 BLI_assert(RNA_property_array_check(prop) != false);
1946 if (prop->arraydimension == 0)
1947 values[0] = bprop->defaultvalue;
1948 else if (bprop->defaultarray)
1949 memcpy(values, bprop->defaultarray, sizeof(int) * prop->totarraylength);
1951 memset(values, 0, sizeof(int) * prop->totarraylength);
1954 int RNA_property_boolean_get_default_index(PointerRNA *ptr, PropertyRNA *prop, int index)
1956 int tmp[RNA_MAX_ARRAY_LENGTH];
1957 int len = rna_ensure_property_array_length(ptr, prop);
1959 BLI_assert(RNA_property_type(prop) == PROP_BOOLEAN);
1960 BLI_assert(RNA_property_array_check(prop) != false);
1961 BLI_assert(index >= 0);
1963 if (len <= RNA_MAX_ARRAY_LENGTH) {
1964 RNA_property_boolean_get_default_array(ptr, prop, tmp);
1968 int *tmparray, value;
1970 tmparray = MEM_callocN(sizeof(int) * len, "RNA_property_boolean_get_default_index");
1971 RNA_property_boolean_get_default_array(ptr, prop, tmparray);
1972 value = tmparray[index];
1973 MEM_freeN(tmparray);
1979 int RNA_property_int_get(PointerRNA *ptr, PropertyRNA *prop)
1981 IntPropertyRNA *iprop = (IntPropertyRNA *)prop;
1984 BLI_assert(RNA_property_type(prop) == PROP_INT);
1985 BLI_assert(RNA_property_array_check(prop) == false);
1987 if ((idprop = rna_idproperty_check(&prop, ptr)))
1988 return IDP_Int(idprop);
1989 else if (iprop->get)
1990 return iprop->get(ptr);
1991 else if (iprop->get_ex)
1992 return iprop->get_ex(ptr, prop);
1994 return iprop->defaultvalue;
1997 void RNA_property_int_set(PointerRNA *ptr, PropertyRNA *prop, int value)
1999 IntPropertyRNA *iprop = (IntPropertyRNA *)prop;
2002 BLI_assert(RNA_property_type(prop) == PROP_INT);
2003 BLI_assert(RNA_property_array_check(prop) == false);
2004 /* useful to check on bad values but set function should clamp */
2005 /* BLI_assert(RNA_property_int_clamp(ptr, prop, &value) == 0); */
2007 if ((idprop = rna_idproperty_check(&prop, ptr))) {
2008 IDP_Int(idprop) = value;
2009 rna_idproperty_touch(idprop);
2011 else if (iprop->set)
2012 iprop->set(ptr, value);
2013 else if (iprop->set_ex)
2014 iprop->set_ex(ptr, prop, value);
2015 else if (prop->flag & PROP_EDITABLE) {
2016 IDPropertyTemplate val = {0};
2019 RNA_property_int_clamp(ptr, prop, &value);
2023 group = RNA_struct_idprops(ptr, 1);
2025 IDP_AddToGroup(group, IDP_New(IDP_INT, &val, prop->identifier));
2029 void RNA_property_int_get_array(PointerRNA *ptr, PropertyRNA *prop, int *values)
2031 IntPropertyRNA *iprop = (IntPropertyRNA *)prop;
2034 BLI_assert(RNA_property_type(prop) == PROP_INT);
2035 BLI_assert(RNA_property_array_check(prop) != false);
2037 if ((idprop = rna_idproperty_check(&prop, ptr))) {
2038 BLI_assert(idprop->len == RNA_property_array_length(ptr, prop));
2039 if (prop->arraydimension == 0)
2040 values[0] = RNA_property_int_get(ptr, prop);
2042 memcpy(values, IDP_Array(idprop), sizeof(int) * idprop->len);
2044 else if (prop->arraydimension == 0)
2045 values[0] = RNA_property_int_get(ptr, prop);
2046 else if (iprop->getarray)
2047 iprop->getarray(ptr, values);
2048 else if (iprop->getarray_ex)
2049 iprop->getarray_ex(ptr, prop, values);
2050 else if (iprop->defaultarray)
2051 memcpy(values, iprop->defaultarray, sizeof(int) * prop->totarraylength);
2053 memset(values, 0, sizeof(int) * prop->totarraylength);
2056 void RNA_property_int_get_array_range(PointerRNA *ptr, PropertyRNA *prop, int values[2])
2058 const int array_len = RNA_property_array_length(ptr, prop);
2060 if (array_len <= 0) {
2064 else if (array_len == 1) {
2065 RNA_property_int_get_array(ptr, prop, values);
2066 values[1] = values[0];
2073 if (array_len > 32) {
2074 arr = MEM_mallocN(sizeof(int) * array_len, "RNA_property_int_get_array_range");
2080 RNA_property_int_get_array(ptr, prop, arr);
2081 values[0] = values[1] = arr[0];
2082 for (i = 1; i < array_len; i++) {
2083 values[0] = MIN2(values[0], arr[i]);
2084 values[1] = MAX2(values[1], arr[i]);
2087 if (arr != arr_stack) {
2093 int RNA_property_int_get_index(PointerRNA *ptr, PropertyRNA *prop, int index)
2095 int tmp[RNA_MAX_ARRAY_LENGTH];
2096 int len = rna_ensure_property_array_length(ptr, prop);
2098 BLI_assert(RNA_property_type(prop) == PROP_INT);
2099 BLI_assert(RNA_property_array_check(prop) != false);
2100 BLI_assert(index >= 0);
2102 if (len <= RNA_MAX_ARRAY_LENGTH) {
2103 RNA_property_int_get_array(ptr, prop, tmp);
2107 int *tmparray, value;
2109 tmparray = MEM_callocN(sizeof(int) * len, "RNA_property_int_get_index");
2110 RNA_property_int_get_array(ptr, prop, tmparray);
2111 value = tmparray[index];
2112 MEM_freeN(tmparray);
2118 void RNA_property_int_set_array(PointerRNA *ptr, PropertyRNA *prop, const int *values)
2120 IntPropertyRNA *iprop = (IntPropertyRNA *)prop;
2123 BLI_assert(RNA_property_type(prop) == PROP_INT);
2124 BLI_assert(RNA_property_array_check(prop) != false);
2126 if ((idprop = rna_idproperty_check(&prop, ptr))) {
2127 BLI_assert(idprop->len == RNA_property_array_length(ptr, prop));
2128 if (prop->arraydimension == 0)
2129 IDP_Int(idprop) = values[0];
2131 memcpy(IDP_Array(idprop), values, sizeof(int) * idprop->len);
2133 rna_idproperty_touch(idprop);
2135 else if (prop->arraydimension == 0)
2136 RNA_property_int_set(ptr, prop, values[0]);
2137 else if (iprop->setarray)
2138 iprop->setarray(ptr, values);
2139 else if (iprop->setarray_ex)
2140 iprop->setarray_ex(ptr, prop, values);
2141 else if (prop->flag & PROP_EDITABLE) {
2142 IDPropertyTemplate val = {0};
2145 /* TODO: RNA_property_int_clamp_array(ptr, prop, &value); */
2147 val.array.len = prop->totarraylength;
2148 val.array.type = IDP_INT;
2150 group = RNA_struct_idprops(ptr, 1);
2152 idprop = IDP_New(IDP_ARRAY, &val, prop->identifier);
2153 IDP_AddToGroup(group, idprop);
2154 memcpy(IDP_Array(idprop), values, sizeof(int) * idprop->len);
2159 void RNA_property_int_set_index(PointerRNA *ptr, PropertyRNA *prop, int index, int value)
2161 int tmp[RNA_MAX_ARRAY_LENGTH];
2162 int len = rna_ensure_property_array_length(ptr, prop);
2164 BLI_assert(RNA_property_type(prop) == PROP_INT);
2165 BLI_assert(RNA_property_array_check(prop) != false);
2166 BLI_assert(index >= 0);
2168 if (len <= RNA_MAX_ARRAY_LENGTH) {
2169 RNA_property_int_get_array(ptr, prop, tmp);
2171 RNA_property_int_set_array(ptr, prop, tmp);
2176 tmparray = MEM_callocN(sizeof(int) * len, "RNA_property_int_get_index");
2177 RNA_property_int_get_array(ptr, prop, tmparray);
2178 tmparray[index] = value;
2179 RNA_property_int_set_array(ptr, prop, tmparray);
2180 MEM_freeN(tmparray);
2184 int RNA_property_int_get_default(PointerRNA *UNUSED(ptr), PropertyRNA *prop)
2186 IntPropertyRNA *iprop = (IntPropertyRNA *)rna_ensure_property(prop);
2187 return iprop->defaultvalue;
2190 void RNA_property_int_get_default_array(PointerRNA *UNUSED(ptr), PropertyRNA *prop, int *values)
2192 IntPropertyRNA *iprop = (IntPropertyRNA *)rna_ensure_property(prop);
2194 BLI_assert(RNA_property_type(prop) == PROP_INT);
2195 BLI_assert(RNA_property_array_check(prop) != false);
2197 if (prop->arraydimension == 0)
2198 values[0] = iprop->defaultvalue;
2199 else if (iprop->defaultarray)
2200 memcpy(values, iprop->defaultarray, sizeof(int) * prop->totarraylength);
2202 memset(values, 0, sizeof(int) * prop->totarraylength);
2205 int RNA_property_int_get_default_index(PointerRNA *ptr, PropertyRNA *prop, int index)
2207 int tmp[RNA_MAX_ARRAY_LENGTH];
2208 int len = rna_ensure_property_array_length(ptr, prop);
2210 BLI_assert(RNA_property_type(prop) == PROP_INT);
2211 BLI_assert(RNA_property_array_check(prop) != false);
2212 BLI_assert(index >= 0);
2214 if (len <= RNA_MAX_ARRAY_LENGTH) {
2215 RNA_property_int_get_default_array(ptr, prop, tmp);
2219 int *tmparray, value;
2221 tmparray = MEM_callocN(sizeof(int) * len, "RNA_property_int_get_default_index");
2222 RNA_property_int_get_default_array(ptr, prop, tmparray);
2223 value = tmparray[index];
2224 MEM_freeN(tmparray);
2230 float RNA_property_float_get(PointerRNA *ptr, PropertyRNA *prop)
2232 FloatPropertyRNA *fprop = (FloatPropertyRNA *)prop;
2235 BLI_assert(RNA_property_type(prop) == PROP_FLOAT);
2236 BLI_assert(RNA_property_array_check(prop) == false);
2238 if ((idprop = rna_idproperty_check(&prop, ptr))) {
2239 if (idprop->type == IDP_FLOAT)
2240 return IDP_Float(idprop);
2242 return (float)IDP_Double(idprop);
2244 else if (fprop->get)
2245 return fprop->get(ptr);
2246 else if (fprop->get_ex)
2247 return fprop->get_ex(ptr, prop);
2249 return fprop->defaultvalue;
2252 void RNA_property_float_set(PointerRNA *ptr, PropertyRNA *prop, float value)
2254 FloatPropertyRNA *fprop = (FloatPropertyRNA *)prop;
2257 BLI_assert(RNA_property_type(prop) == PROP_FLOAT);
2258 BLI_assert(RNA_property_array_check(prop) == false);
2259 /* useful to check on bad values but set function should clamp */
2260 /* BLI_assert(RNA_property_float_clamp(ptr, prop, &value) == 0); */
2262 if ((idprop = rna_idproperty_check(&prop, ptr))) {
2263 if (idprop->type == IDP_FLOAT)
2264 IDP_Float(idprop) = value;
2266 IDP_Double(idprop) = value;
2268 rna_idproperty_touch(idprop);
2270 else if (fprop->set) {
2271 fprop->set(ptr, value);
2273 else if (fprop->set_ex) {
2274 fprop->set_ex(ptr, prop, value);
2276 else if (prop->flag & PROP_EDITABLE) {
2277 IDPropertyTemplate val = {0};
2280 RNA_property_float_clamp(ptr, prop, &value);
2284 group = RNA_struct_idprops(ptr, 1);
2286 IDP_AddToGroup(group, IDP_New(IDP_FLOAT, &val, prop->identifier));
2290 void RNA_property_float_get_array(PointerRNA *ptr, PropertyRNA *prop, float *values)
2292 FloatPropertyRNA *fprop = (FloatPropertyRNA *)prop;
2296 BLI_assert(RNA_property_type(prop) == PROP_FLOAT);
2297 BLI_assert(RNA_property_array_check(prop) != false);
2299 if ((idprop = rna_idproperty_check(&prop, ptr))) {
2300 BLI_assert(idprop->len == RNA_property_array_length(ptr, prop));
2301 if (prop->arraydimension == 0)
2302 values[0] = RNA_property_float_get(ptr, prop);
2303 else if (idprop->subtype == IDP_FLOAT) {
2304 memcpy(values, IDP_Array(idprop), sizeof(float) * idprop->len);
2307 for (i = 0; i < idprop->len; i++)
2308 values[i] = (float)(((double *)IDP_Array(idprop))[i]);
2311 else if (prop->arraydimension == 0)
2312 values[0] = RNA_property_float_get(ptr, prop);
2313 else if (fprop->getarray)
2314 fprop->getarray(ptr, values);
2315 else if (fprop->getarray_ex)
2316 fprop->getarray_ex(ptr, prop, values);
2317 else if (fprop->defaultarray)
2318 memcpy(values, fprop->defaultarray, sizeof(float) * prop->totarraylength);
2320 memset(values, 0, sizeof(float) * prop->totarraylength);
2323 void RNA_property_float_get_array_range(PointerRNA *ptr, PropertyRNA *prop, float values[2])
2325 const int array_len = RNA_property_array_length(ptr, prop);
2327 if (array_len <= 0) {
2331 else if (array_len == 1) {
2332 RNA_property_float_get_array(ptr, prop, values);
2333 values[1] = values[0];
2336 float arr_stack[32];
2340 if (array_len > 32) {
2341 arr = MEM_mallocN(sizeof(float) * array_len, "RNA_property_float_get_array_range");
2347 RNA_property_float_get_array(ptr, prop, arr);
2348 values[0] = values[1] = arr[0];
2349 for (i = 1; i < array_len; i++) {
2350 values[0] = MIN2(values[0], arr[i]);
2351 values[1] = MAX2(values[1], arr[i]);
2354 if (arr != arr_stack) {
2360 float RNA_property_float_get_index(PointerRNA *ptr, PropertyRNA *prop, int index)
2362 float tmp[RNA_MAX_ARRAY_LENGTH];
2363 int len = rna_ensure_property_array_length(ptr, prop);
2365 BLI_assert(RNA_property_type(prop) == PROP_FLOAT);
2366 BLI_assert(RNA_property_array_check(prop) != false);
2367 BLI_assert(index >= 0);
2369 if (len <= RNA_MAX_ARRAY_LENGTH) {
2370 RNA_property_float_get_array(ptr, prop, tmp);
2374 float *tmparray, value;
2376 tmparray = MEM_callocN(sizeof(float) * len, "RNA_property_float_get_index");
2377 RNA_property_float_get_array(ptr, prop, tmparray);
2378 value = tmparray[index];
2379 MEM_freeN(tmparray);
2385 void RNA_property_float_set_array(PointerRNA *ptr, PropertyRNA *prop, const float *values)
2387 FloatPropertyRNA *fprop = (FloatPropertyRNA *)prop;
2391 BLI_assert(RNA_property_type(prop) == PROP_FLOAT);
2392 BLI_assert(RNA_property_array_check(prop) != false);
2394 if ((idprop = rna_idproperty_check(&prop, ptr))) {
2395 BLI_assert(idprop->len == RNA_property_array_length(ptr, prop));
2396 if (prop->arraydimension == 0) {
2397 if (idprop->type == IDP_FLOAT)
2398 IDP_Float(idprop) = values[0];
2400 IDP_Double(idprop) = values[0];
2402 else if (idprop->subtype == IDP_FLOAT) {
2403 memcpy(IDP_Array(idprop), values, sizeof(float) * idprop->len);
2406 for (i = 0; i < idprop->len; i++)
2407 ((double *)IDP_Array(idprop))[i] = values[i];
2410 rna_idproperty_touch(idprop);
2412 else if (prop->arraydimension == 0)
2413 RNA_property_float_set(ptr, prop, values[0]);
2414 else if (fprop->setarray) {
2415 fprop->setarray(ptr, values);
2417 else if (fprop->setarray_ex) {
2418 fprop->setarray_ex(ptr, prop, values);
2420 else if (prop->flag & PROP_EDITABLE) {
2421 IDPropertyTemplate val = {0};
2424 /* TODO: RNA_property_float_clamp_array(ptr, prop, &value); */
2426 val.array.len = prop->totarraylength;
2427 val.array.type = IDP_FLOAT;
2429 group = RNA_struct_idprops(ptr, 1);
2431 idprop = IDP_New(IDP_ARRAY, &val, prop->identifier);
2432 IDP_AddToGroup(group, idprop);
2433 memcpy(IDP_Array(idprop), values, sizeof(float) * idprop->len);
2438 void RNA_property_float_set_index(PointerRNA *ptr, PropertyRNA *prop, int index, float value)
2440 float tmp[RNA_MAX_ARRAY_LENGTH];
2441 int len = rna_ensure_property_array_length(ptr, prop);
2443 BLI_assert(RNA_property_type(prop) == PROP_FLOAT);
2444 BLI_assert(RNA_property_array_check(prop) != false);
2445 BLI_assert(index >= 0);
2447 if (len <= RNA_MAX_ARRAY_LENGTH) {
2448 RNA_property_float_get_array(ptr, prop, tmp);
2450 RNA_property_float_set_array(ptr, prop, tmp);
2455 tmparray = MEM_callocN(sizeof(float) * len, "RNA_property_float_get_index");
2456 RNA_property_float_get_array(ptr, prop, tmparray);
2457 tmparray[index] = value;
2458 RNA_property_float_set_array(ptr, prop, tmparray);
2459 MEM_freeN(tmparray);
2463 float RNA_property_float_get_default(PointerRNA *UNUSED(ptr), PropertyRNA *prop)
2465 FloatPropertyRNA *fprop = (FloatPropertyRNA *)rna_ensure_property(prop);
2467 BLI_assert(RNA_property_type(prop) == PROP_FLOAT);
2468 BLI_assert(RNA_property_array_check(prop) == false);
2470 return fprop->defaultvalue;
2473 void RNA_property_float_get_default_array(PointerRNA *UNUSED(ptr), PropertyRNA *prop, float *values)
2475 FloatPropertyRNA *fprop = (FloatPropertyRNA *)rna_ensure_property(prop);
2477 BLI_assert(RNA_property_type(prop) == PROP_FLOAT);
2478 BLI_assert(RNA_property_array_check(prop) != false);
2480 if (prop->arraydimension == 0)
2481 values[0] = fprop->defaultvalue;
2482 else if (fprop->defaultarray)
2483 memcpy(values, fprop->defaultarray, sizeof(float) * prop->totarraylength);
2485 memset(values, 0, sizeof(float) * prop->totarraylength);
2488 float RNA_property_float_get_default_index(PointerRNA *ptr, PropertyRNA *prop, int index)
2490 float tmp[RNA_MAX_ARRAY_LENGTH];
2491 int len = rna_ensure_property_array_length(ptr, prop);
2493 BLI_assert(RNA_property_type(prop) == PROP_FLOAT);
2494 BLI_assert(RNA_property_array_check(prop) != false);
2495 BLI_assert(index >= 0);
2497 if (len <= RNA_MAX_ARRAY_LENGTH) {
2498 RNA_property_float_get_default_array(ptr, prop, tmp);
2502 float *tmparray, value;
2504 tmparray = MEM_callocN(sizeof(float) * len, "RNA_property_float_get_default_index");
2505 RNA_property_float_get_default_array(ptr, prop, tmparray);
2506 value = tmparray[index];
2507 MEM_freeN(tmparray);
2513 void RNA_property_string_get(PointerRNA *ptr, PropertyRNA *prop, char *value)
2515 StringPropertyRNA *sprop = (StringPropertyRNA *)prop;
2518 BLI_assert(RNA_property_type(prop) == PROP_STRING);
2520 if ((idprop = rna_idproperty_check(&prop, ptr))) {
2521 /* editing bytes is not 100% supported
2522 * since they can contain NIL chars */
2523 if (idprop->subtype == IDP_STRING_SUB_BYTE) {
2524 memcpy(value, IDP_String(idprop), idprop->len);
2525 value[idprop->len] = '\0';
2528 memcpy(value, IDP_String(idprop), idprop->len);
2531 else if (sprop->get) {
2532 sprop->get(ptr, value);
2534 else if (sprop->get_ex) {
2535 sprop->get_ex(ptr, prop, value);
2538 strcpy(value, sprop->defaultvalue);
2542 char *RNA_property_string_get_alloc(PointerRNA *ptr, PropertyRNA *prop,
2543 char *fixedbuf, int fixedlen, int *r_len)
2548 BLI_assert(RNA_property_type(prop) == PROP_STRING);
2550 length = RNA_property_string_length(ptr, prop);
2552 if (length + 1 < fixedlen)
2555 buf = MEM_mallocN(sizeof(char) * (length + 1), "RNA_string_get_alloc");
2558 /* safety check to ensure the string is actually set */
2562 RNA_property_string_get(ptr, prop, buf);
2565 BLI_assert(buf[length] == '\0');
2575 /* this is the length without \0 terminator */
2576 int RNA_property_string_length(PointerRNA *ptr, PropertyRNA *prop)
2578 StringPropertyRNA *sprop = (StringPropertyRNA *)prop;
2581 BLI_assert(RNA_property_type(prop) == PROP_STRING);
2583 if ((idprop = rna_idproperty_check(&prop, ptr))) {
2584 if (idprop->subtype == IDP_STRING_SUB_BYTE) {
2589 /* these _must_ stay in sync */
2590 BLI_assert(strlen(IDP_String(idprop)) == idprop->len - 1);
2592 return idprop->len - 1;
2595 else if (sprop->length)
2596 return sprop->length(ptr);
2597 else if (sprop->length_ex)
2598 return sprop->length_ex(ptr, prop);
2600 return strlen(sprop->defaultvalue);
2603 void RNA_property_string_set(PointerRNA *ptr, PropertyRNA *prop, const char *value)
2605 StringPropertyRNA *sprop = (StringPropertyRNA *)prop;
2608 BLI_assert(RNA_property_type(prop) == PROP_STRING);
2610 if ((idprop = rna_idproperty_check(&prop, ptr))) {
2611 /* both IDP_STRING_SUB_BYTE / IDP_STRING_SUB_UTF8 */
2612 IDP_AssignString(idprop, value, RNA_property_string_maxlength(prop) - 1);
2613 rna_idproperty_touch(idprop);
2615 else if (sprop->set)
2616 sprop->set(ptr, value); /* set function needs to clamp its self */
2617 else if (sprop->set_ex)
2618 sprop->set_ex(ptr, prop, value); /* set function needs to clamp its self */
2619 else if (prop->flag & PROP_EDITABLE) {
2622 group = RNA_struct_idprops(ptr, 1);
2624 IDP_AddToGroup(group, IDP_NewString(value, prop->identifier, RNA_property_string_maxlength(prop)));
2628 void RNA_property_string_get_default(PointerRNA *UNUSED(ptr), PropertyRNA *prop, char *value)
2630 StringPropertyRNA *sprop = (StringPropertyRNA *)rna_ensure_property(prop);
2632 BLI_assert(RNA_property_type(prop) == PROP_STRING);
2634 strcpy(value, sprop->defaultvalue);
2637 char *RNA_property_string_get_default_alloc(PointerRNA *ptr, PropertyRNA *prop, char *fixedbuf, int fixedlen)
2642 BLI_assert(RNA_property_type(prop) == PROP_STRING);
2644 length = RNA_property_string_default_length(ptr, prop);
2646 if (length + 1 < fixedlen)
2649 buf = MEM_callocN(sizeof(char) * (length + 1), "RNA_string_get_alloc");
2651 RNA_property_string_get_default(ptr, prop, buf);
2656 /* this is the length without \0 terminator */
2657 int RNA_property_string_default_length(PointerRNA *UNUSED(ptr), PropertyRNA *prop)
2659 StringPropertyRNA *sprop = (StringPropertyRNA *)prop;
2661 BLI_assert(RNA_property_type(prop) == PROP_STRING);
2663 return strlen(sprop->defaultvalue);
2666 int RNA_property_enum_get(PointerRNA *ptr, PropertyRNA *prop)
2668 EnumPropertyRNA *eprop = (EnumPropertyRNA *)prop;
2671 BLI_assert(RNA_property_type(prop) == PROP_ENUM);
2673 if ((idprop = rna_idproperty_check(&prop, ptr)))
2674 return IDP_Int(idprop);
2675 else if (eprop->get)
2676 return eprop->get(ptr);
2677 else if (eprop->get_ex)
2678 return eprop->get_ex(ptr, prop);
2680 return eprop->defaultvalue;
2683 void RNA_property_enum_set(PointerRNA *ptr, PropertyRNA *prop, int value)
2685 EnumPropertyRNA *eprop = (EnumPropertyRNA *)prop;
2688 BLI_assert(RNA_property_type(prop) == PROP_ENUM);
2690 if ((idprop = rna_idproperty_check(&prop, ptr))) {
2691 IDP_Int(idprop) = value;
2692 rna_idproperty_touch(idprop);
2694 else if (eprop->set) {
2695 eprop->set(ptr, value);
2697 else if (eprop->set_ex) {
2698 eprop->set_ex(ptr, prop, value);
2700 else if (prop->flag & PROP_EDITABLE) {
2701 IDPropertyTemplate val = {0};
2706 group = RNA_struct_idprops(ptr, 1);
2708 IDP_AddToGroup(group, IDP_New(IDP_INT, &val, prop->identifier));
2712 int RNA_property_enum_get_default(PointerRNA *UNUSED(ptr), PropertyRNA *prop)
2714 EnumPropertyRNA *eprop = (EnumPropertyRNA *)rna_ensure_property(prop);
2716 BLI_assert(RNA_property_type(prop) == PROP_ENUM);
2718 return eprop->defaultvalue;
2721 void *RNA_property_enum_py_data_get(PropertyRNA *prop)
2723 EnumPropertyRNA *eprop = (EnumPropertyRNA *)prop;
2725 BLI_assert(RNA_property_type(prop) == PROP_ENUM);
2727 return eprop->py_data;
2730 PointerRNA RNA_property_pointer_get(PointerRNA *ptr, PropertyRNA *prop)
2732 PointerPropertyRNA *pprop = (PointerPropertyRNA *)prop;
2735 BLI_assert(RNA_property_type(prop) == PROP_POINTER);
2737 if ((idprop = rna_idproperty_check(&prop, ptr))) {
2738 pprop = (PointerPropertyRNA *)prop;
2740 /* for groups, data is idprop itself */
2742 return rna_pointer_inherit_refine(ptr, pprop->typef(ptr), idprop);
2744 return rna_pointer_inherit_refine(ptr, pprop->type, idprop);
2746 else if (pprop->get) {
2747 return pprop->get(ptr);
2749 else if (prop->flag & PROP_IDPROPERTY) {
2750 /* XXX temporary hack to add it automatically, reading should
2751 * never do any write ops, to ensure thread safety etc .. */
2752 RNA_property_pointer_add(ptr, prop);
2753 return RNA_property_pointer_get(ptr, prop);
2756 return PointerRNA_NULL;
2760 void RNA_property_pointer_set(PointerRNA *ptr, PropertyRNA *prop, PointerRNA ptr_value)
2762 /*IDProperty *idprop;*/
2764 BLI_assert(RNA_property_type(prop) == PROP_POINTER);
2766 if ((/*idprop = */ rna_idproperty_check(&prop, ptr))) {
2768 /* rna_idproperty_touch(idprop); */
2771 PointerPropertyRNA *pprop = (PointerPropertyRNA *)prop;
2774 !((prop->flag & PROP_NEVER_NULL) && ptr_value.data == NULL) &&
2775 !((prop->flag & PROP_ID_SELF_CHECK) && ptr->id.data == ptr_value.id.data))
2777 pprop->set(ptr, ptr_value);
2782 PointerRNA RNA_property_pointer_get_default(PointerRNA *UNUSED(ptr), PropertyRNA *UNUSED(prop))
2784 /*PointerPropertyRNA *pprop = (PointerPropertyRNA *)prop; */
2786 /* BLI_assert(RNA_property_type(prop) == PROP_POINTER); */
2788 return PointerRNA_NULL; /* FIXME: there has to be a way... */
2791 void RNA_property_pointer_add(PointerRNA *ptr, PropertyRNA *prop)
2793 /*IDProperty *idprop;*/
2795 BLI_assert(RNA_property_type(prop) == PROP_POINTER);
2797 if ((/*idprop=*/ rna_idproperty_check(&prop, ptr))) {
2798 /* already exists */
2800 else if (prop->flag & PROP_IDPROPERTY) {
2801 IDPropertyTemplate val = {0};
2806 group = RNA_struct_idprops(ptr, 1);
2808 IDP_AddToGroup(group, IDP_New(IDP_GROUP, &val, prop->identifier));
2811 printf("%s %s.%s: only supported for id properties.\n", __func__, ptr->type->identifier, prop->identifier);
2814 void RNA_property_pointer_remove(PointerRNA *ptr, PropertyRNA *prop)
2816 IDProperty *idprop, *group;
2818 BLI_assert(RNA_property_type(prop) == PROP_POINTER);
2820 if ((idprop = rna_idproperty_check(&prop, ptr))) {
2821 group = RNA_struct_idprops(ptr, 0);
2824 IDP_FreeFromGroup(group, idprop);
2828 printf("%s %s.%s: only supported for id properties.\n", __func__, ptr->type->identifier, prop->identifier);
2831 static void rna_property_collection_get_idp(CollectionPropertyIterator *iter)
2833 CollectionPropertyRNA *cprop = (CollectionPropertyRNA *)iter->prop;
2835 iter->ptr.data = rna_iterator_array_get(iter);
2836 iter->ptr.type = cprop->item_type;
2837 rna_pointer_inherit_id(cprop->item_type, &iter->parent, &iter->ptr);
2840 void RNA_property_collection_begin(PointerRNA *ptr, PropertyRNA *prop, CollectionPropertyIterator *iter)
2844 BLI_assert(RNA_property_type(prop) == PROP_COLLECTION);
2846 memset(iter, 0, sizeof(*iter));
2848 if ((idprop = rna_idproperty_check(&prop, ptr)) || (prop->flag & PROP_IDPROPERTY)) {
2849 iter->parent = *ptr;
2853 rna_iterator_array_begin(iter, IDP_IDPArray(idprop), sizeof(IDProperty), idprop->len, 0, NULL);
2855 rna_iterator_array_begin(iter, NULL, sizeof(IDProperty), 0, 0, NULL);
2858 rna_property_collection_get_idp(iter);
2863 CollectionPropertyRNA *cprop = (CollectionPropertyRNA *)prop;
2864 cprop->begin(iter, ptr);
2868 void RNA_property_collection_next(CollectionPropertyIterator *iter)
2870 CollectionPropertyRNA *cprop = (CollectionPropertyRNA *)rna_ensure_property(iter->prop);
2873 rna_iterator_array_next(iter);
2876 rna_property_collection_get_idp(iter);
2882 void RNA_property_collection_skip(CollectionPropertyIterator *iter, int num)
2884 CollectionPropertyRNA *cprop = (CollectionPropertyRNA *)rna_ensure_property(iter->prop);
2887 if (num > 1 && (iter->idprop || (cprop->property.flag & PROP_RAW_ARRAY))) {
2888 /* fast skip for array */
2889 ArrayIterator *internal = &iter->internal.array;
2891 if (!internal->skip) {
2892 internal->ptr += internal->itemsize * (num - 1);
2893 iter->valid = (internal->ptr < internal->endptr);
2895 RNA_property_collection_next(iter);
2900 /* slow iteration otherwise */
2901 for (i = 0; i < num && iter->valid; i++)
2902 RNA_property_collection_next(iter);
2905 void RNA_property_collection_end(CollectionPropertyIterator *iter)
2907 CollectionPropertyRNA *cprop = (CollectionPropertyRNA *)rna_ensure_property(iter->prop);
2910 rna_iterator_array_end(iter);
2915 int RNA_property_collection_length(PointerRNA *ptr, PropertyRNA *prop)
2917 CollectionPropertyRNA *cprop = (CollectionPropertyRNA *)prop;
2920 BLI_assert(RNA_property_type(prop) == PROP_COLLECTION);
2922 if ((idprop = rna_idproperty_check(&prop, ptr))) {
2925 else if (cprop->length) {
2926 return cprop->length(ptr);
2929 CollectionPropertyIterator iter;
2932 RNA_property_collection_begin(ptr, prop, &iter);
2933 for (; iter.valid; RNA_property_collection_next(&iter))
2935 RNA_property_collection_end(&iter);
2941 void RNA_property_collection_add(PointerRNA *ptr, PropertyRNA *prop, PointerRNA *r_ptr)
2944 /* CollectionPropertyRNA *cprop = (CollectionPropertyRNA *)prop; */
2946 BLI_assert(RNA_property_type(prop) == PROP_COLLECTION);
2948 if ((idprop = rna_idproperty_check(&prop, ptr))) {
2949 IDPropertyTemplate val = {0};
2952 item = IDP_New(IDP_GROUP, &val, "");
2953 IDP_AppendArray(idprop, item);
2954 /* IDP_FreeProperty(item); *//* IDP_AppendArray does a shallow copy (memcpy), only free memory */
2956 rna_idproperty_touch(idprop);
2958 else if (prop->flag & PROP_IDPROPERTY) {
2959 IDProperty *group, *item;
2960 IDPropertyTemplate val = {0};
2962 group = RNA_struct_idprops(ptr, 1);
2964 idprop = IDP_NewIDPArray(prop->identifier);
2965 IDP_AddToGroup(group, idprop);
2967 item = IDP_New(IDP_GROUP, &val, "");
2968 IDP_AppendArray(idprop, item);
2969 /* IDP_FreeProperty(item); *//* IDP_AppendArray does a shallow copy (memcpy), only free memory */
2974 /* py api calls directly */
2976 else if (cprop->add) {
2977 if (!(cprop->add->flag & FUNC_USE_CONTEXT)) { /* XXX check for this somewhere else */
2978 ParameterList params;
2979 RNA_parameter_list_create(¶ms, ptr, cprop->add);
2980 RNA_function_call(NULL, NULL, ptr, cprop->add, ¶ms);
2981 RNA_parameter_list_free(¶ms);
2985 printf("%s %s.%s: not implemented for this property.\n", __func__, ptr->type->identifier, prop->identifier);*/
2990 CollectionPropertyRNA *cprop = (CollectionPropertyRNA *)prop;
2992 r_ptr->data = IDP_GetIndexArray(idprop, idprop->len - 1);
2993 r_ptr->type = cprop->item_type;
2994 rna_pointer_inherit_id(NULL, ptr, r_ptr);
2997 memset(r_ptr, 0, sizeof(*r_ptr));
3001 bool RNA_property_collection_remove(PointerRNA *ptr, PropertyRNA *prop, int key)
3004 /* CollectionPropertyRNA *cprop = (CollectionPropertyRNA *)prop; */
3006 BLI_assert(RNA_property_type(prop) == PROP_COLLECTION);
3008 if ((idprop = rna_idproperty_check(&prop, ptr))) {
3009 IDProperty tmp, *array;
3013 array = IDP_IDPArray(idprop);
3015 if (key >= 0 && key < len) {
3016 if (key + 1 < len) {
3017 /* move element to be removed to the back */
3018 memcpy(&tmp, &array[key], sizeof(IDProperty));
3019 memmove(array + key, array + key + 1, sizeof(IDProperty) * (len - (key + 1)));
3020 memcpy(&array[len - 1], &tmp, sizeof(IDProperty));
3023 IDP_ResizeIDPArray(idprop, len - 1);
3028 else if (prop->flag & PROP_IDPROPERTY) {
3032 /* py api calls directly */
3034 else if (cprop->remove) {
3035 if (!(cprop->remove->flag & FUNC_USE_CONTEXT)) { /* XXX check for this somewhere else */
3036 ParameterList params;
3037 RNA_parameter_list_create(¶ms, ptr, cprop->remove);
3038 RNA_function_call(NULL, NULL, ptr, cprop->remove, ¶ms);
3039 RNA_parameter_list_free(¶ms);
3045 printf("%s %s.%s: only supported for id properties.\n", __func__, ptr->type->identifier, prop->identifier);*/
3050 bool RNA_property_collection_move(PointerRNA *ptr, PropertyRNA *prop, int key, int pos)
3054 BLI_assert(RNA_property_type(prop) == PROP_COLLECTION);
3056 if ((idprop = rna_idproperty_check(&prop, ptr))) {
3057 IDProperty tmp, *array;
3061 array = IDP_IDPArray(idprop);
3063 if (key >= 0 && key < len && pos >= 0 && pos < len && key != pos) {
3064 memcpy(&tmp, &array[key], sizeof(IDProperty));
3066 memmove(array + pos + 1, array + pos, sizeof(IDProperty) * (key - pos));
3068 memmove(array + key, array + key + 1, sizeof(IDProperty) * (pos - key));
3069 memcpy(&array[pos], &tmp, sizeof(IDProperty));
3074 else if (prop->flag & PROP_IDPROPERTY) {
3081 void RNA_property_collection_clear(PointerRNA *ptr, PropertyRNA *prop)
3085 BLI_assert(RNA_property_type(prop) == PROP_COLLECTION);
3087 if ((idprop = rna_idproperty_check(&prop, ptr))) {
3088 IDP_ResizeIDPArray(idprop, 0);
3089 rna_idproperty_touch(idprop);
3093 int RNA_property_collection_lookup_index(PointerRNA *ptr, PropertyRNA *prop, PointerRNA *t_ptr)
3095 CollectionPropertyIterator iter;
3098 BLI_assert(RNA_property_type(prop) == PROP_COLLECTION);
3100 RNA_property_collection_begin(ptr, prop, &iter);
3101 for (index = 0; iter.valid; RNA_property_collection_next(&iter), index++) {
3102 if (iter.ptr.data == t_ptr->data)
3105 RNA_property_collection_end(&iter);
3107 /* did we find it? */
3114 int RNA_property_collection_lookup_int(PointerRNA *ptr, PropertyRNA *prop, int key, PointerRNA *r_ptr)
3116 CollectionPropertyRNA *cprop = (CollectionPropertyRNA *)rna_ensure_property(prop);
3118 BLI_assert(RNA_property_type(prop) == PROP_COLLECTION);
3120 if (cprop->lookupint) {
3121 /* we have a callback defined, use it */
3122 return cprop->lookupint(ptr, key, r_ptr);
3125 /* no callback defined, just iterate and find the nth item */
3126 CollectionPropertyIterator iter;
3129 RNA_property_collection_begin(ptr, prop, &iter);
3130 for (i = 0; iter.valid; RNA_property_collection_next(&iter), i++) {
3136 RNA_property_collection_end(&iter);
3139 memset(r_ptr, 0, sizeof(*r_ptr));
3145 int RNA_property_collection_lookup_string(PointerRNA *ptr, PropertyRNA *prop, const char *key, PointerRNA *r_ptr)
3147 CollectionPropertyRNA *cprop = (CollectionPropertyRNA *)rna_ensure_property(prop);
3149 BLI_assert(RNA_property_type(prop) == PROP_COLLECTION);
3151 if (cprop->lookupstring) {
3152 /* we have a callback defined, use it */
3153 return cprop->lookupstring(ptr, key, r_ptr);
3156 /* no callback defined, compare with name properties if they exist */
3157 CollectionPropertyIterator iter;
3158 PropertyRNA *nameprop;
3159 char name[256], *nameptr;
3161 int keylen = strlen(key);
3164 RNA_property_collection_begin(ptr, prop, &iter);
3165 for (; iter.valid; RNA_property_collection_next(&iter)) {
3166 if (iter.ptr.data && iter.ptr.type->nameproperty) {
3167 nameprop = iter.ptr.type->nameproperty;
3169 nameptr = RNA_property_string_get_alloc(&iter.ptr, nameprop, name, sizeof(name), &namelen);
3171 if ((keylen == namelen) && (strcmp(nameptr, key) == 0)) {
3176 if ((char *)&name != nameptr)
3183 RNA_property_collection_end(&iter);
3186 memset(r_ptr, 0, sizeof(*r_ptr));
3192 /* zero return is an assignment error */
3193 int RNA_property_collection_assign_int(PointerRNA *ptr, PropertyRNA *prop, const int key, const PointerRNA *assign_ptr)
3195 CollectionPropertyRNA *cprop = (CollectionPropertyRNA *)rna_ensure_property(prop);
3197 BLI_assert(RNA_property_type(prop) == PROP_COLLECTION);
3199 if (cprop->assignint) {
3200 /* we have a callback defined, use it */
3201 return cprop->assignint(ptr, key, assign_ptr);
3207 bool RNA_property_collection_type_get(PointerRNA *ptr, PropertyRNA *prop, PointerRNA *r_ptr)
3209 BLI_assert(RNA_property_type(prop) == PROP_COLLECTION);
3212 return ((r_ptr->type = rna_ensure_property(prop)->srna) ? 1 : 0);
3215 int RNA_property_collection_raw_array(PointerRNA *ptr, PropertyRNA *prop, PropertyRNA *itemprop, RawArray *array)
3217 CollectionPropertyIterator iter;
3218 ArrayIterator *internal;
3221 BLI_assert(RNA_property_type(prop) == PROP_COLLECTION);
3223 if (!(prop->flag & PROP_RAW_ARRAY) || !(itemprop->flag & PROP_RAW_ACCESS))
3226 RNA_property_collection_begin(ptr, prop, &iter);
3229 /* get data from array iterator and item property */
3230 internal = &iter.internal.array;
3231 arrayp = (iter.valid) ? iter.ptr.data : NULL;
3233 if (internal->skip || !RNA_property_editable(&iter.ptr, itemprop)) {
3234 /* we might skip some items, so it's not a proper array */
3235 RNA_property_collection_end(&iter);
3239 array->array = arrayp + itemprop->rawoffset;
3240 array->stride = internal->itemsize;
3241 array->len = ((char *)internal->endptr - arrayp) / internal->itemsize;
3242 array->type = itemprop->rawtype;
3245 memset(array, 0, sizeof(RawArray));
3247 RNA_property_collection_end(&iter);
3252 #define RAW_GET(dtype, var, raw, a) \
3254 switch (raw.type) { \
3255 case PROP_RAW_CHAR: var = (dtype)((char *)raw.array)[a]; break; \
3256 case PROP_RAW_SHORT: var = (dtype)((short *)raw.array)[a]; break; \
3257 case PROP_RAW_INT: var = (dtype)((int *)raw.array)[a]; break; \
3258 case PROP_RAW_FLOAT: var = (dtype)((float *)raw.array)[a]; break; \
3259 case PROP_RAW_DOUBLE: var = (dtype)((double *)raw.array)[a]; break; \
3260 default: var = (dtype)0; \
3264 #define RAW_SET(dtype, raw, a, var) \
3266 switch (raw.type) { \
3267 case PROP_RAW_CHAR: ((char *)raw.array)[a] = (char)var; break; \
3268 case PROP_RAW_SHORT: ((short *)raw.array)[a] = (short)var; break; \
3269 case PROP_RAW_INT: ((int *)raw.array)[a] = (int)var; break; \
3270 case PROP_RAW_FLOAT: ((float *)raw.array)[a] = (float)var; break; \
3271 case PROP_RAW_DOUBLE: ((double *)raw.array)[a] = (double)var; break; \
3276 int RNA_raw_type_sizeof(RawPropertyType type)
3279 case PROP_RAW_CHAR: return sizeof(char);
3280 case PROP_RAW_SHORT: return sizeof(short);
3281 case PROP_RAW_INT: return sizeof(int);
3282 case PROP_RAW_FLOAT: return sizeof(float);
3283 case PROP_RAW_DOUBLE: return sizeof(double);
3288 static int rna_property_array_length_all_dimensions(PointerRNA *ptr, PropertyRNA *prop)
3290 int i, len[RNA_MAX_ARRAY_DIMENSION];
3291 const int dim = RNA_property_array_dimension(ptr, prop, len);
3297 for (size = 1, i = 0; i < dim; i++)
3303 static int rna_raw_access(ReportList *reports, PointerRNA *ptr, PropertyRNA *prop, const char *propname,
3304 void *inarray, RawPropertyType intype, int inlen, int set)
3308 PropertyRNA *itemprop, *iprop;
3309 PropertyType itemtype = 0;
3313 /* initialize in array, stride assumed 0 in following code */
3319 ptype = RNA_property_pointer_type(ptr, prop);
3321 /* try to get item property pointer */
3322 RNA_pointer_create(NULL, ptype, NULL, &itemptr);
3323 itemprop = RNA_struct_find_property(&itemptr, propname);
3326 /* we have item property pointer */
3330 itemtype = RNA_property_type(itemprop);
3332 if (!ELEM3(itemtype, PROP_BOOLEAN, PROP_INT, PROP_FLOAT)) {
3333 BKE_report(reports, RPT_ERROR, "Only boolean, int and float properties supported");
3337 /* check item array */
3338 itemlen = RNA_property_array_length(&itemptr, itemprop);
3340 /* dynamic array? need to get length per item */
3341 if (itemprop->getlength) {
3344 /* try to access as raw array */
3345 else if (RNA_property_collection_raw_array(ptr, prop, itemprop, &out)) {
3346 int arraylen = (itemlen == 0) ? 1 : itemlen;
3347 if (in.len != arraylen * out.len) {
3348 BKE_reportf(reports, RPT_ERROR, "Array length mismatch (expected %d, got %d)",
3349 out.len * arraylen, in.len);
3353 /* matching raw types */
3354 if (out.type == in.type) {
3355 void *inp = in.array;
3356 void *outp = out.array;
3359 size = RNA_raw_type_sizeof(out.type) * arraylen;
3361 for (a = 0; a < out.len; a++) {
3362 if (set) memcpy(outp, inp, size);
3363 else memcpy(inp, outp, size);
3365 inp = (char *)inp + size;
3366 outp = (char *)outp + out.stride;
3372 /* could also be faster with non-matching types,
3373 * for now we just do slower loop .. */
3378 void *tmparray = NULL;
3380 int err = 0, j, a = 0;
3383 if (((itemtype == PROP_BOOLEAN || itemtype == PROP_INT) && in.type == PROP_RAW_INT) ||
3384 (itemtype == PROP_FLOAT && in.type == PROP_RAW_FLOAT))
3386 /* avoid creating temporary buffer if the data type match */