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 "BLT_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"
53 #include "BKE_library.h"
55 #include "BKE_report.h"
57 #include "RNA_access.h"
58 #include "RNA_define.h"
59 #include "RNA_enum_types.h"
64 #include "DNA_object_types.h"
65 #include "BKE_depsgraph.h"
68 #include "rna_internal.h"
70 const PointerRNA PointerRNA_NULL = {{NULL}};
79 for (srna = BLENDER_RNA.structs.first; srna; srna = srna->cont.next) {
80 if (!srna->cont.prophash) {
81 srna->cont.prophash = BLI_ghash_str_new("RNA_init gh");
83 for (prop = srna->cont.properties.first; prop; prop = prop->next) {
84 if (!(prop->flag_internal & PROP_INTERN_BUILTIN)) {
85 BLI_ghash_insert(srna->cont.prophash, (void *)prop->identifier, prop);
96 RNA_property_update_cache_free();
98 for (srna = BLENDER_RNA.structs.first; srna; srna = srna->cont.next) {
99 if (srna->cont.prophash) {
100 BLI_ghash_free(srna->cont.prophash, NULL, NULL);
101 srna->cont.prophash = NULL;
105 RNA_free(&BLENDER_RNA);
110 void RNA_main_pointer_create(struct Main *main, PointerRNA *r_ptr)
112 r_ptr->id.data = NULL;
113 r_ptr->type = &RNA_BlendData;
117 void RNA_id_pointer_create(ID *id, PointerRNA *r_ptr)
119 StructRNA *type, *idtype = NULL;
122 PointerRNA tmp = {{NULL}};
124 idtype = rna_ID_refine(&tmp);
126 while (idtype->refine) {
127 type = idtype->refine(&tmp);
137 r_ptr->type = idtype;
141 void RNA_pointer_create(ID *id, StructRNA *type, void *data, PointerRNA *r_ptr)
144 StructRNA *idtype = NULL;
147 PointerRNA tmp = {{0}};
149 idtype = rna_ID_refine(&tmp);
158 while (r_ptr->type && r_ptr->type->refine) {
159 StructRNA *rtype = r_ptr->type->refine(r_ptr);
161 if (rtype == r_ptr->type)
169 static void rna_pointer_inherit_id(StructRNA *type, PointerRNA *parent, PointerRNA *ptr)
171 if (type && type->flag & STRUCT_ID) {
172 ptr->id.data = ptr->data;
175 ptr->id.data = parent->id.data;
179 void RNA_blender_rna_pointer_create(PointerRNA *r_ptr)
181 r_ptr->id.data = NULL;
182 r_ptr->type = &RNA_BlenderRNA;
183 r_ptr->data = &BLENDER_RNA;
186 PointerRNA rna_pointer_inherit_refine(PointerRNA *ptr, StructRNA *type, void *data)
192 rna_pointer_inherit_id(type, ptr, &result);
194 while (result.type->refine) {
195 type = result.type->refine(&result);
197 if (type == result.type)
205 return PointerRNA_NULL;
210 void RNA_pointer_recast(PointerRNA *ptr, PointerRNA *r_ptr)
212 #if 0 /* works but this case if covered by more general code below. */
213 if (RNA_struct_is_ID(ptr->type)) {
215 RNA_id_pointer_create(ptr->id.data, r_ptr);
222 *r_ptr = *ptr; /* initialize as the same in case cant recast */
224 for (base = ptr->type->base; base; base = base->base) {
225 t_ptr = rna_pointer_inherit_refine(ptr, base, ptr->data);
226 if (t_ptr.type && t_ptr.type != ptr->type) {
235 static void rna_idproperty_touch(IDProperty *idprop)
237 /* so the property is seen as 'set' by rna */
238 idprop->flag &= ~IDP_FLAG_GHOST;
241 /* return a UI local ID prop definition for this prop */
242 static IDProperty *rna_idproperty_ui(PropertyRNA *prop)
246 for (idprop = ((IDProperty *)prop)->prev; idprop; idprop = idprop->prev) {
247 if (STREQ(RNA_IDP_UI, idprop->name))
251 if (idprop == NULL) {
252 for (idprop = ((IDProperty *)prop)->next; idprop; idprop = idprop->next) {
253 if (STREQ(RNA_IDP_UI, idprop->name))
259 return IDP_GetPropertyTypeFromGroup(idprop, ((IDProperty *)prop)->name, IDP_GROUP);
265 IDProperty *RNA_struct_idprops(PointerRNA *ptr, bool create)
267 StructRNA *type = ptr->type;
269 if (type && type->idproperties)
270 return type->idproperties(ptr, create);
275 bool RNA_struct_idprops_check(StructRNA *srna)
277 return (srna && srna->idproperties);
280 static IDProperty *rna_idproperty_find(PointerRNA *ptr, const char *name)
282 IDProperty *group = RNA_struct_idprops(ptr, 0);
285 return IDP_GetPropertyFromGroup(group, name);
290 static void rna_idproperty_free(PointerRNA *ptr, const char *name)
292 IDProperty *group = RNA_struct_idprops(ptr, 0);
295 IDProperty *idprop = IDP_GetPropertyFromGroup(group, name);
297 IDP_FreeFromGroup(group, idprop);
302 static int rna_ensure_property_array_length(PointerRNA *ptr, PropertyRNA *prop)
304 if (prop->magic == RNA_MAGIC) {
305 int arraylen[RNA_MAX_ARRAY_DIMENSION];
306 return (prop->getlength && ptr->data) ? prop->getlength(ptr, arraylen) : prop->totarraylength;
309 IDProperty *idprop = (IDProperty *)prop;
311 if (idprop->type == IDP_ARRAY)
318 static bool rna_ensure_property_array_check(PropertyRNA *prop)
320 if (prop->magic == RNA_MAGIC) {
321 return (prop->getlength || prop->totarraylength);
324 IDProperty *idprop = (IDProperty *)prop;
326 return (idprop->type == IDP_ARRAY);
330 static void rna_ensure_property_multi_array_length(PointerRNA *ptr, PropertyRNA *prop, int length[])
332 if (prop->magic == RNA_MAGIC) {
334 prop->getlength(ptr, length);
336 memcpy(length, prop->arraylength, prop->arraydimension * sizeof(int));
339 IDProperty *idprop = (IDProperty *)prop;
341 if (idprop->type == IDP_ARRAY)
342 length[0] = idprop->len;
348 static bool rna_idproperty_verify_valid(PointerRNA *ptr, PropertyRNA *prop, IDProperty *idprop)
350 /* this verifies if the idproperty actually matches the property
351 * description and otherwise removes it. this is to ensure that
352 * rna property access is type safe, e.g. if you defined the rna
353 * to have a certain array length you can count on that staying so */
355 switch (idprop->type) {
357 if (prop->type != PROP_COLLECTION)
361 if (rna_ensure_property_array_length(ptr, prop) != idprop->len)
364 if (idprop->subtype == IDP_FLOAT && prop->type != PROP_FLOAT)
366 if (idprop->subtype == IDP_INT && !ELEM(prop->type, PROP_BOOLEAN, PROP_INT, PROP_ENUM))
371 if (!ELEM(prop->type, PROP_BOOLEAN, PROP_INT, PROP_ENUM))
376 if (prop->type != PROP_FLOAT)
380 if (prop->type != PROP_STRING)
385 if (prop->type != PROP_POINTER)
395 static PropertyRNA *typemap[IDP_NUMTYPES] = {
396 (PropertyRNA *)&rna_PropertyGroupItem_string,
397 (PropertyRNA *)&rna_PropertyGroupItem_int,
398 (PropertyRNA *)&rna_PropertyGroupItem_float,
400 (PropertyRNA *)&rna_PropertyGroupItem_group,
401 (PropertyRNA *)&rna_PropertyGroupItem_id,
402 (PropertyRNA *)&rna_PropertyGroupItem_double,
403 (PropertyRNA *)&rna_PropertyGroupItem_idp_array
406 static PropertyRNA *arraytypemap[IDP_NUMTYPES] = {
407 NULL, (PropertyRNA *)&rna_PropertyGroupItem_int_array,
408 (PropertyRNA *)&rna_PropertyGroupItem_float_array,
410 (PropertyRNA *)&rna_PropertyGroupItem_collection, NULL,
411 (PropertyRNA *)&rna_PropertyGroupItem_double_array
414 IDProperty *rna_idproperty_check(PropertyRNA **prop, PointerRNA *ptr)
416 /* This is quite a hack, but avoids some complexity in the API. we
417 * pass IDProperty structs as PropertyRNA pointers to the outside.
418 * We store some bytes in PropertyRNA structs that allows us to
419 * distinguish it from IDProperty structs. If it is an ID property,
420 * we look up an IDP PropertyRNA based on the type, and set the data
421 * pointer to the IDProperty. */
423 if ((*prop)->magic == RNA_MAGIC) {
424 if ((*prop)->flag & PROP_IDPROPERTY) {
425 IDProperty *idprop = rna_idproperty_find(ptr, (*prop)->identifier);
427 if (idprop && !rna_idproperty_verify_valid(ptr, *prop, idprop)) {
428 IDProperty *group = RNA_struct_idprops(ptr, 0);
430 IDP_FreeFromGroup(group, idprop);
441 IDProperty *idprop = (IDProperty *)(*prop);
443 if (idprop->type == IDP_ARRAY)
444 *prop = arraytypemap[(int)(idprop->subtype)];
446 *prop = typemap[(int)(idprop->type)];
452 static PropertyRNA *rna_ensure_property(PropertyRNA *prop)
454 /* the quick version if we don't need the idproperty */
456 if (prop->magic == RNA_MAGIC)
460 IDProperty *idprop = (IDProperty *)prop;
462 if (idprop->type == IDP_ARRAY)
463 return arraytypemap[(int)(idprop->subtype)];
465 return typemap[(int)(idprop->type)];
469 static const char *rna_ensure_property_identifier(const PropertyRNA *prop)
471 if (prop->magic == RNA_MAGIC)
472 return prop->identifier;
474 return ((const IDProperty *)prop)->name;
477 static const char *rna_ensure_property_description(PropertyRNA *prop)
479 const char *description = NULL;
481 if (prop->magic == RNA_MAGIC)
482 description = prop->description;
484 /* attempt to get the local ID values */
485 IDProperty *idp_ui = rna_idproperty_ui(prop);
488 IDProperty *item = IDP_GetPropertyTypeFromGroup(idp_ui, "description", IDP_STRING);
490 description = IDP_String(item);
493 if (description == NULL)
494 description = ((IDProperty *)prop)->name; /* XXX - not correct */
500 static const char *rna_ensure_property_name(const PropertyRNA *prop)
504 if (prop->magic == RNA_MAGIC)
507 name = ((const IDProperty *)prop)->name;
514 StructRNA *RNA_struct_find(const char *identifier)
518 for (type = BLENDER_RNA.structs.first; type; type = type->cont.next)
519 if (STREQ(type->identifier, identifier))
525 const char *RNA_struct_identifier(const StructRNA *type)
527 return type->identifier;
530 const char *RNA_struct_ui_name(const StructRNA *type)
532 return CTX_IFACE_(type->translation_context, type->name);
535 const char *RNA_struct_ui_name_raw(const StructRNA *type)
540 int RNA_struct_ui_icon(const StructRNA *type)
548 const char *RNA_struct_ui_description(const StructRNA *type)
550 return TIP_(type->description);
553 const char *RNA_struct_ui_description_raw(const StructRNA *type)
555 return type->description;
558 const char *RNA_struct_translation_context(const StructRNA *type)
560 return type->translation_context;
563 PropertyRNA *RNA_struct_name_property(StructRNA *type)
565 return type->nameproperty;
568 PropertyRNA *RNA_struct_iterator_property(StructRNA *type)
570 return type->iteratorproperty;
573 StructRNA *RNA_struct_base(StructRNA *type)
578 bool RNA_struct_is_ID(const StructRNA *type)
580 return (type->flag & STRUCT_ID) != 0;
583 bool RNA_struct_undo_check(const StructRNA *type)
585 return (type->flag & STRUCT_UNDO) != 0;
588 bool RNA_struct_idprops_register_check(const StructRNA *type)
590 return (type->flag & STRUCT_NO_IDPROPERTIES) == 0;
593 bool RNA_struct_idprops_datablock_allowed(const StructRNA *type)
595 return (type->flag & (STRUCT_NO_DATABLOCK_IDPROPERTIES | STRUCT_NO_IDPROPERTIES)) == 0;
599 * Whether given type implies datablock usage by IDProperties.
600 * This is used to prevent classes allowed to have IDProperties, but not datablock ones, to indirectly use some
601 * (e.g. by assigning an IDP_GROUP containing some IDP_ID pointers...).
603 bool RNA_struct_idprops_contains_datablock(const StructRNA *type)
605 return (type->flag & (STRUCT_CONTAINS_DATABLOCK_IDPROPERTIES | STRUCT_ID)) != 0;
608 /* remove an id-property */
609 bool RNA_struct_idprops_unset(PointerRNA *ptr, const char *identifier)
611 IDProperty *group = RNA_struct_idprops(ptr, 0);
614 IDProperty *idp = IDP_GetPropertyFromGroup(group, identifier);
616 IDP_FreeFromGroup(group, idp);
624 bool RNA_struct_is_a(const StructRNA *type, const StructRNA *srna)
626 const StructRNA *base;
628 if (srna == &RNA_AnyType)
634 /* ptr->type is always maximally refined */
635 for (base = type; base; base = base->base)
642 PropertyRNA *RNA_struct_find_property(PointerRNA *ptr, const char *identifier)
644 if (identifier[0] == '[' && identifier[1] == '"') { /* " (dummy comment to avoid confusing some
645 * function lists in text editors) */
646 /* id prop lookup, not so common */
647 PropertyRNA *r_prop = NULL;
648 PointerRNA r_ptr; /* only support single level props */
649 if (RNA_path_resolve_property(ptr, identifier, &r_ptr, &r_prop) &&
650 (r_ptr.type == ptr->type) && (r_ptr.data == ptr->data))
656 /* most common case */
657 PropertyRNA *iterprop = RNA_struct_iterator_property(ptr->type);
660 if (RNA_property_collection_lookup_string(ptr, iterprop, identifier, &propptr))
667 /* Find the property which uses the given nested struct */
668 static PropertyRNA *RNA_struct_find_nested(PointerRNA *ptr, StructRNA *srna)
670 PropertyRNA *prop = NULL;
672 RNA_STRUCT_BEGIN (ptr, iprop)
674 /* This assumes that there can only be one user of this nested struct */
675 if (RNA_property_pointer_type(ptr, iprop) == srna) {
685 bool RNA_struct_contains_property(PointerRNA *ptr, PropertyRNA *prop_test)
687 /* note, prop_test could be freed memory, only use for comparison */
689 /* validate the RNA is ok */
690 PropertyRNA *iterprop;
693 iterprop = RNA_struct_iterator_property(ptr->type);
695 RNA_PROP_BEGIN (ptr, itemptr, iterprop)
697 /* PropertyRNA *prop = itemptr.data; */
698 if (prop_test == (PropertyRNA *)itemptr.data) {
708 /* low level direct access to type->properties, note this ignores parent classes so should be used with care */
709 const struct ListBase *RNA_struct_type_properties(StructRNA *srna)
711 return &srna->cont.properties;
714 PropertyRNA *RNA_struct_type_find_property(StructRNA *srna, const char *identifier)
716 return BLI_findstring_ptr(&srna->cont.properties, identifier, offsetof(PropertyRNA, identifier));
719 FunctionRNA *RNA_struct_find_function(StructRNA *srna, const char *identifier)
724 for (type = srna; type; type = type->base) {
725 func = (FunctionRNA *)BLI_findstring_ptr(&type->functions, identifier, offsetof(FunctionRNA, identifier));
732 /* funcitonal but slow */
735 PropertyRNA *iterprop;
738 RNA_pointer_create(NULL, &RNA_Struct, srna, &tptr);
739 iterprop = RNA_struct_find_property(&tptr, "functions");
743 RNA_PROP_BEGIN (&tptr, funcptr, iterprop)
745 if (STREQ(identifier, RNA_function_identifier(funcptr.data))) {
756 const ListBase *RNA_struct_type_functions(StructRNA *srna)
758 return &srna->functions;
761 StructRegisterFunc RNA_struct_register(StructRNA *type)
766 StructUnregisterFunc RNA_struct_unregister(StructRNA *type)
771 } while ((type = type->base));
776 void **RNA_struct_instance(PointerRNA *ptr)
778 StructRNA *type = ptr->type;
782 return type->instance(ptr);
783 } while ((type = type->base));
788 void *RNA_struct_py_type_get(StructRNA *srna)
790 return srna->py_type;
793 void RNA_struct_py_type_set(StructRNA *srna, void *py_type)
795 srna->py_type = py_type;
798 void *RNA_struct_blender_type_get(StructRNA *srna)
800 return srna->blender_type;
803 void RNA_struct_blender_type_set(StructRNA *srna, void *blender_type)
805 srna->blender_type = blender_type;
808 char *RNA_struct_name_get_alloc(PointerRNA *ptr, char *fixedbuf, int fixedlen, int *r_len)
810 PropertyRNA *nameprop;
812 if (ptr->data && (nameprop = RNA_struct_name_property(ptr->type)))
813 return RNA_property_string_get_alloc(ptr, nameprop, fixedbuf, fixedlen, r_len);
818 /* Property Information */
820 const char *RNA_property_identifier(PropertyRNA *prop)
822 return rna_ensure_property_identifier(prop);
825 const char *RNA_property_description(PropertyRNA *prop)
827 return TIP_(rna_ensure_property_description(prop));
830 PropertyType RNA_property_type(PropertyRNA *prop)
832 return rna_ensure_property(prop)->type;
835 PropertySubType RNA_property_subtype(PropertyRNA *prop)
837 return rna_ensure_property(prop)->subtype;
840 PropertyUnit RNA_property_unit(PropertyRNA *prop)
842 return RNA_SUBTYPE_UNIT(rna_ensure_property(prop)->subtype);
845 int RNA_property_flag(PropertyRNA *prop)
847 return rna_ensure_property(prop)->flag;
850 bool RNA_property_builtin(PropertyRNA *prop)
852 return (rna_ensure_property(prop)->flag_internal & PROP_INTERN_BUILTIN) != 0;
855 void *RNA_property_py_data_get(PropertyRNA *prop)
857 return prop->py_data;
860 int RNA_property_array_length(PointerRNA *ptr, PropertyRNA *prop)
862 return rna_ensure_property_array_length(ptr, prop);
865 bool RNA_property_array_check(PropertyRNA *prop)
867 return rna_ensure_property_array_check(prop);
870 /* used by BPY to make an array from the python object */
871 int RNA_property_array_dimension(PointerRNA *ptr, PropertyRNA *prop, int length[])
873 PropertyRNA *rprop = rna_ensure_property(prop);
876 rna_ensure_property_multi_array_length(ptr, prop, length);
878 return rprop->arraydimension;
881 /* Return the size of Nth dimension. */
882 int RNA_property_multi_array_length(PointerRNA *ptr, PropertyRNA *prop, int dim)
884 int len[RNA_MAX_ARRAY_DIMENSION];
886 rna_ensure_property_multi_array_length(ptr, prop, len);
891 char RNA_property_array_item_char(PropertyRNA *prop, int index)
893 const char *vectoritem = "XYZW";
894 const char *quatitem = "WXYZ";
895 const char *coloritem = "RGBA";
896 PropertySubType subtype = rna_ensure_property(prop)->subtype;
898 BLI_assert(index >= 0);
900 /* get string to use for array index */
901 if ((index < 4) && ELEM(subtype, PROP_QUATERNION, PROP_AXISANGLE)) {
902 return quatitem[index];
904 else if ((index < 4) && ELEM(subtype, PROP_TRANSLATION, PROP_DIRECTION, PROP_XYZ, PROP_XYZ_LENGTH,
905 PROP_EULER, PROP_VELOCITY, PROP_ACCELERATION, PROP_COORDS))
907 return vectoritem[index];
909 else if ((index < 4) && ELEM(subtype, PROP_COLOR, PROP_COLOR_GAMMA)) {
910 return coloritem[index];
916 int RNA_property_array_item_index(PropertyRNA *prop, char name)
918 PropertySubType subtype = rna_ensure_property(prop)->subtype;
920 /* get index based on string name/alias */
921 /* maybe a function to find char index in string would be better than all the switches */
922 if (ELEM(subtype, PROP_QUATERNION, PROP_AXISANGLE)) {
934 else if (ELEM(subtype, PROP_TRANSLATION, PROP_DIRECTION, PROP_XYZ, PROP_XYZ_LENGTH,
935 PROP_EULER, PROP_VELOCITY, PROP_ACCELERATION))
948 else if (ELEM(subtype, PROP_COLOR, PROP_COLOR_GAMMA)) {
965 void RNA_property_int_range(PointerRNA *ptr, PropertyRNA *prop, int *hardmin, int *hardmax)
967 IntPropertyRNA *iprop = (IntPropertyRNA *)rna_ensure_property(prop);
968 int softmin, softmax;
970 if (prop->magic != RNA_MAGIC) {
971 /* attempt to get the local ID values */
972 IDProperty *idp_ui = rna_idproperty_ui(prop);
977 item = IDP_GetPropertyTypeFromGroup(idp_ui, "min", IDP_INT);
978 *hardmin = item ? IDP_Int(item) : INT_MIN;
980 item = IDP_GetPropertyTypeFromGroup(idp_ui, "max", IDP_INT);
981 *hardmax = item ? IDP_Int(item) : INT_MAX;
991 iprop->range(ptr, hardmin, hardmax, &softmin, &softmax);
993 else if (iprop->range_ex) {
997 iprop->range_ex(ptr, prop, hardmin, hardmax, &softmin, &softmax);
1000 *hardmin = iprop->hardmin;
1001 *hardmax = iprop->hardmax;
1005 void RNA_property_int_ui_range(PointerRNA *ptr, PropertyRNA *prop, int *softmin, int *softmax, int *step)
1007 IntPropertyRNA *iprop = (IntPropertyRNA *)rna_ensure_property(prop);
1008 int hardmin, hardmax;
1010 if (prop->magic != RNA_MAGIC) {
1011 /* attempt to get the local ID values */
1012 IDProperty *idp_ui = rna_idproperty_ui(prop);
1017 item = IDP_GetPropertyTypeFromGroup(idp_ui, "soft_min", IDP_INT);
1018 *softmin = item ? IDP_Int(item) : INT_MIN;
1020 item = IDP_GetPropertyTypeFromGroup(idp_ui, "soft_max", IDP_INT);
1021 *softmax = item ? IDP_Int(item) : INT_MAX;
1023 item = IDP_GetPropertyTypeFromGroup(idp_ui, "step", IDP_INT);
1024 *step = item ? IDP_Int(item) : 1;
1030 *softmin = iprop->softmin;
1031 *softmax = iprop->softmax;
1037 iprop->range(ptr, &hardmin, &hardmax, softmin, softmax);
1039 *softmin = max_ii(*softmin, hardmin);
1040 *softmax = min_ii(*softmax, hardmax);
1042 else if (iprop->range_ex) {
1046 iprop->range_ex(ptr, prop, &hardmin, &hardmax, softmin, softmax);
1048 *softmin = max_ii(*softmin, hardmin);
1049 *softmax = min_ii(*softmax, hardmax);
1052 *step = iprop->step;
1055 void RNA_property_float_range(PointerRNA *ptr, PropertyRNA *prop, float *hardmin, float *hardmax)
1057 FloatPropertyRNA *fprop = (FloatPropertyRNA *)rna_ensure_property(prop);
1058 float softmin, softmax;
1060 if (prop->magic != RNA_MAGIC) {
1061 /* attempt to get the local ID values */
1062 IDProperty *idp_ui = rna_idproperty_ui(prop);
1067 item = IDP_GetPropertyTypeFromGroup(idp_ui, "min", IDP_DOUBLE);
1068 *hardmin = item ? (float)IDP_Double(item) : -FLT_MAX;
1070 item = IDP_GetPropertyTypeFromGroup(idp_ui, "max", IDP_DOUBLE);
1071 *hardmax = item ? (float)IDP_Double(item) : FLT_MAX;
1078 *hardmin = -FLT_MAX;
1081 fprop->range(ptr, hardmin, hardmax, &softmin, &softmax);
1083 else if (fprop->range_ex) {
1084 *hardmin = -FLT_MAX;
1087 fprop->range_ex(ptr, prop, hardmin, hardmax, &softmin, &softmax);
1090 *hardmin = fprop->hardmin;
1091 *hardmax = fprop->hardmax;
1095 void RNA_property_float_ui_range(PointerRNA *ptr, PropertyRNA *prop, float *softmin, float *softmax,
1096 float *step, float *precision)
1098 FloatPropertyRNA *fprop = (FloatPropertyRNA *)rna_ensure_property(prop);
1099 float hardmin, hardmax;
1101 if (prop->magic != RNA_MAGIC) {
1102 /* attempt to get the local ID values */
1103 IDProperty *idp_ui = rna_idproperty_ui(prop);
1108 item = IDP_GetPropertyTypeFromGroup(idp_ui, "soft_min", IDP_DOUBLE);
1109 *softmin = item ? (float)IDP_Double(item) : -FLT_MAX;
1111 item = IDP_GetPropertyTypeFromGroup(idp_ui, "soft_max", IDP_DOUBLE);
1112 *softmax = item ? (float)IDP_Double(item) : FLT_MAX;
1114 item = IDP_GetPropertyTypeFromGroup(idp_ui, "step", IDP_DOUBLE);
1115 *step = item ? (float)IDP_Double(item) : 1.0f;
1117 item = IDP_GetPropertyTypeFromGroup(idp_ui, "precision", IDP_DOUBLE);
1118 *precision = item ? (float)IDP_Double(item) : 3.0f;
1124 *softmin = fprop->softmin;
1125 *softmax = fprop->softmax;
1131 fprop->range(ptr, &hardmin, &hardmax, softmin, softmax);
1133 *softmin = max_ff(*softmin, hardmin);
1134 *softmax = min_ff(*softmax, hardmax);
1136 else if (fprop->range_ex) {
1140 fprop->range_ex(ptr, prop, &hardmin, &hardmax, softmin, softmax);
1142 *softmin = max_ff(*softmin, hardmin);
1143 *softmax = min_ff(*softmax, hardmax);
1146 *step = fprop->step;
1147 *precision = (float)fprop->precision;
1150 int RNA_property_float_clamp(PointerRNA *ptr, PropertyRNA *prop, float *value)
1154 RNA_property_float_range(ptr, prop, &min, &max);
1160 else if (*value > max) {
1169 int RNA_property_int_clamp(PointerRNA *ptr, PropertyRNA *prop, int *value)
1173 RNA_property_int_range(ptr, prop, &min, &max);
1179 else if (*value > max) {
1188 /* this is the max length including \0 terminator.
1189 * '0' used when their is no maximum */
1190 int RNA_property_string_maxlength(PropertyRNA *prop)
1192 StringPropertyRNA *sprop = (StringPropertyRNA *)rna_ensure_property(prop);
1193 return sprop->maxlength;
1196 StructRNA *RNA_property_pointer_type(PointerRNA *ptr, PropertyRNA *prop)
1198 prop = rna_ensure_property(prop);
1200 if (prop->type == PROP_POINTER) {
1201 PointerPropertyRNA *pprop = (PointerPropertyRNA *)prop;
1204 return pprop->typef(ptr);
1205 else if (pprop->type)
1208 else if (prop->type == PROP_COLLECTION) {
1209 CollectionPropertyRNA *cprop = (CollectionPropertyRNA *)prop;
1211 if (cprop->item_type)
1212 return cprop->item_type;
1214 /* ignore other types, RNA_struct_find_nested calls with unchecked props */
1216 return &RNA_UnknownType;
1219 int RNA_property_pointer_poll(PointerRNA *ptr, PropertyRNA *prop, PointerRNA *value)
1221 prop = rna_ensure_property(prop);
1223 if (prop->type == PROP_POINTER) {
1224 PointerPropertyRNA *pprop = (PointerPropertyRNA *)prop;
1227 if (rna_idproperty_check(&prop, ptr)) {
1228 return ((PropPointerPollFuncPy) pprop->poll)(ptr, *value, prop);
1231 return pprop->poll(ptr, *value);
1238 printf("%s: %s is not a pointer property.\n", __func__, prop->identifier);
1242 /* Reuse for dynamic types */
1243 EnumPropertyItem DummyRNA_NULL_items[] = {
1244 {0, NULL, 0, NULL, NULL}
1247 /* Reuse for dynamic types with default value */
1248 EnumPropertyItem DummyRNA_DEFAULT_items[] = {
1249 {0, "DEFAULT", 0, "Default", ""},
1250 {0, NULL, 0, NULL, NULL}
1253 void RNA_property_enum_items_ex(
1254 bContext *C, PointerRNA *ptr, PropertyRNA *prop, const bool use_static,
1255 EnumPropertyItem **r_item, int *r_totitem, bool *r_free)
1257 EnumPropertyRNA *eprop = (EnumPropertyRNA *)rna_ensure_property(prop);
1261 if (!use_static && eprop->itemf && (C != NULL || (prop->flag & PROP_ENUM_NO_CONTEXT))) {
1262 EnumPropertyItem *item;
1264 if (prop->flag & PROP_ENUM_NO_CONTEXT)
1265 item = eprop->itemf(NULL, ptr, prop, r_free);
1267 item = eprop->itemf(C, ptr, prop, r_free);
1269 /* any callbacks returning NULL should be fixed */
1270 BLI_assert(item != NULL);
1274 for (tot = 0; item[tot].identifier; tot++) {
1283 *r_item = eprop->item;
1285 *r_totitem = eprop->totitem;
1289 void RNA_property_enum_items(
1290 bContext *C, PointerRNA *ptr, PropertyRNA *prop, EnumPropertyItem **r_item, int *r_totitem, bool *r_free)
1292 RNA_property_enum_items_ex(C, ptr, prop, false, r_item, r_totitem, r_free);
1295 #ifdef WITH_INTERNATIONAL
1296 static void property_enum_translate(PropertyRNA *prop, EnumPropertyItem **r_item, int *r_totitem, bool *r_free)
1298 if (!(prop->flag & PROP_ENUM_NO_TRANSLATE)) {
1301 /* Note: Only do those tests once, and then use BLT_pgettext. */
1302 bool do_iface = BLT_translate_iface();
1303 bool do_tooltip = BLT_translate_tooltips();
1304 EnumPropertyItem *nitem;
1306 if (!(do_iface || do_tooltip))
1313 EnumPropertyItem *item = *r_item;
1321 for (tot = 0; item[tot].identifier; tot++) {
1326 nitem = MEM_mallocN(sizeof(EnumPropertyItem) * (tot + 1), "enum_items_gettexted");
1327 memcpy(nitem, item, sizeof(EnumPropertyItem) * (tot + 1));
1332 for (i = 0; nitem[i].identifier; i++) {
1333 if (nitem[i].name && do_iface) {
1334 nitem[i].name = BLT_pgettext(prop->translation_context, nitem[i].name);
1336 if (nitem[i].description && do_tooltip) {
1337 nitem[i].description = BLT_pgettext(NULL, nitem[i].description);
1346 void RNA_property_enum_items_gettexted(bContext *C, PointerRNA *ptr, PropertyRNA *prop,
1347 EnumPropertyItem **r_item, int *r_totitem, bool *r_free)
1349 RNA_property_enum_items(C, ptr, prop, r_item, r_totitem, r_free);
1351 #ifdef WITH_INTERNATIONAL
1352 property_enum_translate(prop, r_item, r_totitem, r_free);
1356 void RNA_property_enum_items_gettexted_all(bContext *C, PointerRNA *ptr, PropertyRNA *prop,
1357 EnumPropertyItem **r_item, int *r_totitem, bool *r_free)
1359 EnumPropertyRNA *eprop = (EnumPropertyRNA *)rna_ensure_property(prop);
1360 int mem_size = sizeof(EnumPropertyItem) * (eprop->totitem + 1);
1361 /* first return all items */
1363 *r_item = MEM_mallocN(mem_size, "enum_gettext_all");
1364 memcpy(*r_item, eprop->item, mem_size);
1367 *r_totitem = eprop->totitem;
1369 if (eprop->itemf && (C != NULL || (prop->flag & PROP_ENUM_NO_CONTEXT))) {
1370 EnumPropertyItem *item;
1374 if (prop->flag & PROP_ENUM_NO_CONTEXT)
1375 item = eprop->itemf(NULL, ptr, prop, &free);
1377 item = eprop->itemf(C, ptr, prop, &free);
1379 /* any callbacks returning NULL should be fixed */
1380 BLI_assert(item != NULL);
1382 for (i = 0; i < eprop->totitem; i++) {
1383 bool exists = false;
1386 /* items that do not exist on list are returned, but have their names/identifiers NULLed out */
1387 for (i_fixed = 0; item[i_fixed].identifier; i_fixed++) {
1388 if (STREQ(item[i_fixed].identifier, (*r_item)[i].identifier)) {
1395 (*r_item)[i].name = NULL;
1396 (*r_item)[i].identifier = "";
1404 #ifdef WITH_INTERNATIONAL
1405 property_enum_translate(prop, r_item, r_totitem, r_free);
1409 bool RNA_property_enum_value(bContext *C, PointerRNA *ptr, PropertyRNA *prop, const char *identifier, int *r_value)
1411 EnumPropertyItem *item;
1415 RNA_property_enum_items(C, ptr, prop, &item, NULL, &free);
1418 const int i = RNA_enum_from_identifier(item, identifier);
1420 *r_value = item[i].value;
1437 bool RNA_enum_identifier(EnumPropertyItem *item, const int value, const char **r_identifier)
1439 const int i = RNA_enum_from_value(item, value);
1441 *r_identifier = item[i].identifier;
1449 int RNA_enum_bitflag_identifiers(EnumPropertyItem *item, const int value, const char **r_identifier)
1452 for (; item->identifier; item++) {
1453 if (item->identifier[0] && item->value & value) {
1454 r_identifier[index++] = item->identifier;
1457 r_identifier[index] = NULL;
1461 bool RNA_enum_name(EnumPropertyItem *item, const int value, const char **r_name)
1463 const int i = RNA_enum_from_value(item, value);
1465 *r_name = item[i].name;
1473 bool RNA_enum_description(EnumPropertyItem *item, const int value, const char **r_description)
1475 const int i = RNA_enum_from_value(item, value);
1477 *r_description = item[i].description;
1485 int RNA_enum_from_identifier(EnumPropertyItem *item, const char *identifier)
1488 for (; item->identifier; item++, i++) {
1489 if (item->identifier[0] && STREQ(item->identifier, identifier)) {
1496 int RNA_enum_from_value(EnumPropertyItem *item, const int value)
1499 for (; item->identifier; item++, i++) {
1500 if (item->identifier[0] && item->value == value) {
1507 bool RNA_property_enum_identifier(bContext *C, PointerRNA *ptr, PropertyRNA *prop, const int value,
1508 const char **identifier)
1510 EnumPropertyItem *item = NULL;
1513 RNA_property_enum_items(C, ptr, prop, &item, NULL, &free);
1516 result = RNA_enum_identifier(item, value, identifier);
1525 bool RNA_property_enum_name(bContext *C, PointerRNA *ptr, PropertyRNA *prop, const int value, const char **name)
1527 EnumPropertyItem *item = NULL;
1530 RNA_property_enum_items(C, ptr, prop, &item, NULL, &free);
1533 result = RNA_enum_name(item, value, name);
1542 bool RNA_property_enum_name_gettexted(bContext *C, PointerRNA *ptr, PropertyRNA *prop, const int value, const char **name)
1546 result = RNA_property_enum_name(C, ptr, prop, value, name);
1549 if (!(prop->flag & PROP_ENUM_NO_TRANSLATE)) {
1550 if (BLT_translate_iface()) {
1551 *name = BLT_pgettext(prop->translation_context, *name);
1559 bool RNA_property_enum_item_from_value(
1560 bContext *C, PointerRNA *ptr, PropertyRNA *prop, const int value,
1561 EnumPropertyItem *r_item)
1563 EnumPropertyItem *item = NULL;
1566 RNA_property_enum_items(C, ptr, prop, &item, NULL, &free);
1568 const int i = RNA_enum_from_value(item, value);
1587 bool RNA_property_enum_item_from_value_gettexted(
1588 bContext *C, PointerRNA *ptr, PropertyRNA *prop, const int value,
1589 EnumPropertyItem *r_item)
1593 result = RNA_property_enum_item_from_value(C, ptr, prop, value, r_item);
1595 if (!(prop->flag & PROP_ENUM_NO_TRANSLATE)) {
1596 if (BLT_translate_iface()) {
1597 r_item->name = BLT_pgettext(prop->translation_context, r_item->name);
1604 int RNA_property_enum_bitflag_identifiers(bContext *C, PointerRNA *ptr, PropertyRNA *prop, const int value,
1605 const char **identifier)
1607 EnumPropertyItem *item = NULL;
1610 RNA_property_enum_items(C, ptr, prop, &item, NULL, &free);
1613 result = RNA_enum_bitflag_identifiers(item, value, identifier);
1622 const char *RNA_property_ui_name(PropertyRNA *prop)
1624 return CTX_IFACE_(prop->translation_context, rna_ensure_property_name(prop));
1627 const char *RNA_property_ui_name_raw(PropertyRNA *prop)
1629 return rna_ensure_property_name(prop);
1632 const char *RNA_property_ui_description(PropertyRNA *prop)
1634 return TIP_(rna_ensure_property_description(prop));
1637 const char *RNA_property_ui_description_raw(PropertyRNA *prop)
1639 return rna_ensure_property_description(prop);
1642 const char *RNA_property_translation_context(PropertyRNA *_prop)
1644 PropertyRNA *prop = rna_ensure_property(_prop);
1645 return prop->translation_context;
1648 int RNA_property_ui_icon(PropertyRNA *prop)
1650 return rna_ensure_property(prop)->icon;
1653 bool RNA_property_editable(PointerRNA *ptr, PropertyRNA *prop)
1655 ID *id = ptr->id.data;
1657 const char *dummy_info;
1659 prop = rna_ensure_property(prop);
1660 flag = prop->editable ? prop->editable(ptr, &dummy_info) : prop->flag;
1662 return ((flag & PROP_EDITABLE) &&
1663 (flag & PROP_REGISTER) == 0 &&
1664 (!id || !ID_IS_LINKED_DATABLOCK(id) || (prop->flag & PROP_LIB_EXCEPTION)));
1668 * Version of #RNA_property_editable that tries to return additional info in \a r_info that can be exposed in UI.
1670 bool RNA_property_editable_info(PointerRNA *ptr, PropertyRNA *prop, const char **r_info)
1672 ID *id = ptr->id.data;
1675 prop = rna_ensure_property(prop);
1679 if (prop->editable) {
1680 flag = prop->editable(ptr, r_info);
1684 if ((flag & PROP_EDITABLE) == 0 || (flag & PROP_REGISTER)) {
1685 *r_info = "This property is for internal use only and can't be edited.";
1689 /* property from linked data-block */
1690 if (id && ID_IS_LINKED_DATABLOCK(id) && (prop->flag & PROP_LIB_EXCEPTION) == 0) {
1691 if (!(*r_info)[0]) {
1692 *r_info = "Can't edit this property from a linked data-block.";
1697 return ((flag & PROP_EDITABLE) && (flag & PROP_REGISTER) == 0);
1700 bool RNA_property_editable_flag(PointerRNA *ptr, PropertyRNA *prop)
1703 const char *dummy_info;
1705 prop = rna_ensure_property(prop);
1706 flag = prop->editable ? prop->editable(ptr, &dummy_info) : prop->flag;
1707 return (flag & PROP_EDITABLE) != 0;
1710 /* same as RNA_property_editable(), except this checks individual items in an array */
1711 bool RNA_property_editable_index(PointerRNA *ptr, PropertyRNA *prop, int index)
1716 BLI_assert(index >= 0);
1718 prop = rna_ensure_property(prop);
1722 if (prop->editable) {
1723 const char *dummy_info;
1724 flag &= prop->editable(ptr, &dummy_info);
1727 if (prop->itemeditable)
1728 flag &= prop->itemeditable(ptr, index);
1732 return (flag & PROP_EDITABLE) && (!id || !ID_IS_LINKED_DATABLOCK(id) || (prop->flag & PROP_LIB_EXCEPTION));
1735 bool RNA_property_animateable(PointerRNA *ptr, PropertyRNA *prop)
1737 /* check that base ID-block can support animation data */
1738 if (!id_can_have_animdata(ptr->id.data))
1741 prop = rna_ensure_property(prop);
1743 if (!(prop->flag & PROP_ANIMATABLE))
1746 return (prop->flag & PROP_EDITABLE) != 0;
1749 bool RNA_property_animated(PointerRNA *ptr, PropertyRNA *prop)
1752 bool driven, special;
1757 if (RNA_property_array_check(prop))
1758 len = RNA_property_array_length(ptr, prop);
1760 for (index = 0; index < len; index++) {
1761 if (rna_get_fcurve(ptr, prop, index, NULL, NULL, &driven, &special))
1768 /* this function is to check if its possible to create a valid path from the ID
1769 * its slow so don't call in a loop */
1770 bool RNA_property_path_from_ID_check(PointerRNA *ptr, PropertyRNA *prop)
1772 char *path = RNA_path_from_ID_to_property(ptr, prop);
1778 PropertyRNA *r_prop;
1780 RNA_id_pointer_create(ptr->id.data, &id_ptr);
1781 if (RNA_path_resolve(&id_ptr, path, &r_ptr, &r_prop) == true) {
1782 ret = (prop == r_prop);
1791 static void rna_property_update(bContext *C, Main *bmain, Scene *scene, PointerRNA *ptr, PropertyRNA *prop)
1793 const bool is_rna = (prop->magic == RNA_MAGIC);
1794 prop = rna_ensure_property(prop);
1798 /* ideally no context would be needed for update, but there's some
1799 * parts of the code that need it still, so we have this exception */
1800 if (prop->flag & PROP_CONTEXT_UPDATE) {
1802 if (prop->flag & PROP_CONTEXT_PROPERTY_UPDATE) {
1803 ((ContextPropUpdateFunc)prop->update)(C, ptr, prop);
1806 ((ContextUpdateFunc)prop->update)(C, ptr);
1811 prop->update(bmain, scene, ptr);
1814 WM_main_add_notifier(prop->noteflag, ptr->id.data);
1817 if (!is_rna || (prop->flag & PROP_IDPROPERTY)) {
1818 /* WARNING! This is so property drivers update the display!
1819 * not especially nice */
1820 DAG_id_tag_update(ptr->id.data, OB_RECALC_OB | OB_RECALC_DATA | OB_RECALC_TIME);
1821 WM_main_add_notifier(NC_WINDOW, NULL);
1822 /* Not nice as well, but the only way to make sure material preview
1823 * is updated with custom nodes.
1825 if ((prop->flag & PROP_IDPROPERTY) != 0 &&
1826 (ptr->id.data != NULL) &&
1827 (GS(((ID *)ptr->id.data)->name) == ID_NT))
1829 WM_main_add_notifier(NC_MATERIAL | ND_SHADING, NULL);
1834 /* must keep in sync with 'rna_property_update'
1835 * note, its possible this returns a false positive in the case of PROP_CONTEXT_UPDATE
1836 * but this isn't likely to be a performance problem. */
1837 bool RNA_property_update_check(PropertyRNA *prop)
1839 return (prop->magic != RNA_MAGIC || prop->update || prop->noteflag);
1842 void RNA_property_update(bContext *C, PointerRNA *ptr, PropertyRNA *prop)
1844 rna_property_update(C, CTX_data_main(C), CTX_data_scene(C), ptr, prop);
1847 void RNA_property_update_main(Main *bmain, Scene *scene, PointerRNA *ptr, PropertyRNA *prop)
1849 rna_property_update(NULL, bmain, scene, ptr, prop);
1853 /* RNA Updates Cache ------------------------ */
1854 /* Overview of RNA Update cache system:
1856 * RNA Update calls need to be cached in order to maintain reasonable performance
1857 * of the animation system (i.e. maintaining a somewhat interactive framerate)
1858 * while still allowing updates to be called (necessary in particular for modifier
1859 * property updates to actually work).
1861 * The cache is structured with a dual-layer structure
1862 * - L1 = PointerRNA used as key; id.data is used (it should always be defined,
1863 * and most updates end up using just that anyways)
1864 * - L2 = Update functions to be called on those PointerRNA's
1868 typedef struct tRnaUpdateCacheElem {
1869 struct tRnaUpdateCacheElem *next, *prev;
1871 PointerRNA ptr; /* L1 key - id as primary, data secondary/ignored? */
1872 ListBase L2Funcs; /* L2 functions (LinkData<RnaUpdateFuncRef>) */
1873 } tRnaUpdateCacheElem;
1875 /* cache global (tRnaUpdateCacheElem's) - only accessible using these API calls */
1876 static ListBase rna_updates_cache = {NULL, NULL};
1878 /* ........................... */
1880 void RNA_property_update_cache_add(PointerRNA *ptr, PropertyRNA *prop)
1882 const bool is_rna = (prop->magic == RNA_MAGIC);
1883 tRnaUpdateCacheElem *uce = NULL;
1884 UpdateFunc fn = NULL;
1891 prop = rna_ensure_property(prop);
1893 /* we can only handle update calls with no context args for now (makes animsys updates easier) */
1894 if ((is_rna == false) || (prop->update == NULL) || (prop->flag & PROP_CONTEXT_UPDATE))
1898 /* find cache element for which key matches... */
1899 for (uce = rna_updates_cache.first; uce; uce = uce->next) {
1900 /* just match by id only for now, since most update calls that we'll encounter only really care about this */
1901 /* TODO: later, the cache might need to have some nesting on L1 to cope better
1902 * with these problems + some tagging to indicate we need this */
1903 if (uce->ptr.id.data == ptr->id.data)
1907 /* create new instance */
1908 uce = MEM_callocN(sizeof(tRnaUpdateCacheElem), "tRnaUpdateCacheElem");
1909 BLI_addtail(&rna_updates_cache, uce);
1912 RNA_pointer_create(ptr->id.data, ptr->type, ptr->data, &uce->ptr);
1915 /* check on the update func */
1916 for (ld = uce->L2Funcs.first; ld; ld = ld->next) {
1917 /* stop on match - function already cached */
1921 /* else... if still here, we need to add it */
1922 BLI_addtail(&uce->L2Funcs, BLI_genericNodeN(fn));
1925 void RNA_property_update_cache_flush(Main *bmain, Scene *scene)
1927 tRnaUpdateCacheElem *uce;
1929 /* TODO: should we check that bmain and scene are valid? The above stuff doesn't! */
1931 /* execute the cached updates */
1932 for (uce = rna_updates_cache.first; uce; uce = uce->next) {
1935 for (ld = uce->L2Funcs.first; ld; ld = ld->next) {
1936 UpdateFunc fn = (UpdateFunc)ld->data;
1937 fn(bmain, scene, &uce->ptr);
1942 void RNA_property_update_cache_free(void)
1944 tRnaUpdateCacheElem *uce, *ucn;
1946 for (uce = rna_updates_cache.first; uce; uce = ucn) {
1950 BLI_freelistN(&uce->L2Funcs);
1953 BLI_freelinkN(&rna_updates_cache, uce);
1957 /* ---------------------------------------------------------------------- */
1961 int RNA_property_boolean_get(PointerRNA *ptr, PropertyRNA *prop)
1963 BoolPropertyRNA *bprop = (BoolPropertyRNA *)prop;
1967 BLI_assert(RNA_property_type(prop) == PROP_BOOLEAN);
1968 BLI_assert(RNA_property_array_check(prop) == false);
1970 if ((idprop = rna_idproperty_check(&prop, ptr)))
1971 value = IDP_Int(idprop);
1972 else if (bprop->get)
1973 value = bprop->get(ptr);
1974 else if (bprop->get_ex)
1975 value = bprop->get_ex(ptr, prop);
1977 value = bprop->defaultvalue;
1979 BLI_assert(ELEM(value, false, true));
1984 void RNA_property_boolean_set(PointerRNA *ptr, PropertyRNA *prop, int value)
1986 BoolPropertyRNA *bprop = (BoolPropertyRNA *)prop;
1989 BLI_assert(RNA_property_type(prop) == PROP_BOOLEAN);
1990 BLI_assert(RNA_property_array_check(prop) == false);
1991 BLI_assert(ELEM(value, false, true));
1993 /* just in case other values are passed */
1994 if (value) value = 1;
1996 if ((idprop = rna_idproperty_check(&prop, ptr))) {
1997 IDP_Int(idprop) = value;
1998 rna_idproperty_touch(idprop);
2000 else if (bprop->set) {
2001 bprop->set(ptr, value);
2003 else if (bprop->set_ex) {
2004 bprop->set_ex(ptr, prop, value);
2006 else if (prop->flag & PROP_EDITABLE) {
2007 IDPropertyTemplate val = {0};
2012 group = RNA_struct_idprops(ptr, 1);
2014 IDP_AddToGroup(group, IDP_New(IDP_INT, &val, prop->identifier));
2018 void RNA_property_boolean_get_array(PointerRNA *ptr, PropertyRNA *prop, int *values)
2020 BoolPropertyRNA *bprop = (BoolPropertyRNA *)prop;
2023 BLI_assert(RNA_property_type(prop) == PROP_BOOLEAN);
2024 BLI_assert(RNA_property_array_check(prop) != false);
2026 if ((idprop = rna_idproperty_check(&prop, ptr))) {
2027 if (prop->arraydimension == 0)
2028 values[0] = RNA_property_boolean_get(ptr, prop);
2030 memcpy(values, IDP_Array(idprop), sizeof(int) * idprop->len);
2032 else if (prop->arraydimension == 0)
2033 values[0] = RNA_property_boolean_get(ptr, prop);
2034 else if (bprop->getarray)
2035 bprop->getarray(ptr, values);
2036 else if (bprop->getarray_ex)
2037 bprop->getarray_ex(ptr, prop, values);
2038 else if (bprop->defaultarray)
2039 memcpy(values, bprop->defaultarray, sizeof(int) * prop->totarraylength);
2041 memset(values, 0, sizeof(int) * prop->totarraylength);
2044 int RNA_property_boolean_get_index(PointerRNA *ptr, PropertyRNA *prop, int index)
2046 int tmp[RNA_MAX_ARRAY_LENGTH];
2047 int len = rna_ensure_property_array_length(ptr, prop);
2050 BLI_assert(RNA_property_type(prop) == PROP_BOOLEAN);
2051 BLI_assert(RNA_property_array_check(prop) != false);
2052 BLI_assert(index >= 0);
2053 BLI_assert(index < len);
2055 if (len <= RNA_MAX_ARRAY_LENGTH) {
2056 RNA_property_boolean_get_array(ptr, prop, tmp);
2062 tmparray = MEM_mallocN(sizeof(int) * len, __func__);
2063 RNA_property_boolean_get_array(ptr, prop, tmparray);
2064 value = tmparray[index];
2065 MEM_freeN(tmparray);
2068 BLI_assert(ELEM(value, false, true));
2073 void RNA_property_boolean_set_array(PointerRNA *ptr, PropertyRNA *prop, const int *values)
2075 BoolPropertyRNA *bprop = (BoolPropertyRNA *)prop;
2078 BLI_assert(RNA_property_type(prop) == PROP_BOOLEAN);
2079 BLI_assert(RNA_property_array_check(prop) != false);
2081 if ((idprop = rna_idproperty_check(&prop, ptr))) {
2082 if (prop->arraydimension == 0)
2083 IDP_Int(idprop) = values[0];
2085 memcpy(IDP_Array(idprop), values, sizeof(int) * idprop->len);
2087 rna_idproperty_touch(idprop);
2089 else if (prop->arraydimension == 0)
2090 RNA_property_boolean_set(ptr, prop, values[0]);
2091 else if (bprop->setarray)
2092 bprop->setarray(ptr, values);
2093 else if (bprop->setarray_ex)
2094 bprop->setarray_ex(ptr, prop, values);
2095 else if (prop->flag & PROP_EDITABLE) {
2096 IDPropertyTemplate val = {0};
2099 val.array.len = prop->totarraylength;
2100 val.array.type = IDP_INT;
2102 group = RNA_struct_idprops(ptr, 1);
2104 idprop = IDP_New(IDP_ARRAY, &val, prop->identifier);
2105 IDP_AddToGroup(group, idprop);
2106 memcpy(IDP_Array(idprop), values, sizeof(int) * idprop->len);
2111 void RNA_property_boolean_set_index(PointerRNA *ptr, PropertyRNA *prop, int index, int value)
2113 int tmp[RNA_MAX_ARRAY_LENGTH];
2114 int len = rna_ensure_property_array_length(ptr, prop);
2116 BLI_assert(RNA_property_type(prop) == PROP_BOOLEAN);
2117 BLI_assert(RNA_property_array_check(prop) != false);
2118 BLI_assert(index >= 0);
2119 BLI_assert(index < len);
2120 BLI_assert(ELEM(value, false, true));
2122 if (len <= RNA_MAX_ARRAY_LENGTH) {
2123 RNA_property_boolean_get_array(ptr, prop, tmp);
2125 RNA_property_boolean_set_array(ptr, prop, tmp);
2130 tmparray = MEM_mallocN(sizeof(int) * len, __func__);
2131 RNA_property_boolean_get_array(ptr, prop, tmparray);
2132 tmparray[index] = value;
2133 RNA_property_boolean_set_array(ptr, prop, tmparray);
2134 MEM_freeN(tmparray);
2138 int RNA_property_boolean_get_default(PointerRNA *UNUSED(ptr), PropertyRNA *prop)
2140 BoolPropertyRNA *bprop = (BoolPropertyRNA *)rna_ensure_property(prop);
2142 BLI_assert(RNA_property_type(prop) == PROP_BOOLEAN);
2143 BLI_assert(RNA_property_array_check(prop) == false);
2144 BLI_assert(ELEM(bprop->defaultvalue, false, true));
2146 return bprop->defaultvalue;
2149 void RNA_property_boolean_get_default_array(PointerRNA *UNUSED(ptr), PropertyRNA *prop, int *values)
2151 BoolPropertyRNA *bprop = (BoolPropertyRNA *)rna_ensure_property(prop);
2153 BLI_assert(RNA_property_type(prop) == PROP_BOOLEAN);
2154 BLI_assert(RNA_property_array_check(prop) != false);
2156 if (prop->arraydimension == 0)
2157 values[0] = bprop->defaultvalue;
2158 else if (bprop->defaultarray)
2159 memcpy(values, bprop->defaultarray, sizeof(int) * prop->totarraylength);
2161 memset(values, 0, sizeof(int) * prop->totarraylength);
2164 int RNA_property_boolean_get_default_index(PointerRNA *ptr, PropertyRNA *prop, int index)
2166 int tmp[RNA_MAX_ARRAY_LENGTH];
2167 int len = rna_ensure_property_array_length(ptr, prop);
2169 BLI_assert(RNA_property_type(prop) == PROP_BOOLEAN);
2170 BLI_assert(RNA_property_array_check(prop) != false);
2171 BLI_assert(index >= 0);
2172 BLI_assert(index < prop->totarraylength);
2174 if (len <= RNA_MAX_ARRAY_LENGTH) {
2175 RNA_property_boolean_get_default_array(ptr, prop, tmp);
2179 int *tmparray, value;
2181 tmparray = MEM_mallocN(sizeof(int) * len, __func__);
2182 RNA_property_boolean_get_default_array(ptr, prop, tmparray);
2183 value = tmparray[index];
2184 MEM_freeN(tmparray);
2190 int RNA_property_int_get(PointerRNA *ptr, PropertyRNA *prop)
2192 IntPropertyRNA *iprop = (IntPropertyRNA *)prop;
2195 BLI_assert(RNA_property_type(prop) == PROP_INT);
2196 BLI_assert(RNA_property_array_check(prop) == false);
2198 if ((idprop = rna_idproperty_check(&prop, ptr)))
2199 return IDP_Int(idprop);
2200 else if (iprop->get)
2201 return iprop->get(ptr);
2202 else if (iprop->get_ex)
2203 return iprop->get_ex(ptr, prop);
2205 return iprop->defaultvalue;
2208 void RNA_property_int_set(PointerRNA *ptr, PropertyRNA *prop, int value)
2210 IntPropertyRNA *iprop = (IntPropertyRNA *)prop;
2213 BLI_assert(RNA_property_type(prop) == PROP_INT);
2214 BLI_assert(RNA_property_array_check(prop) == false);
2215 /* useful to check on bad values but set function should clamp */
2216 /* BLI_assert(RNA_property_int_clamp(ptr, prop, &value) == 0); */
2218 if ((idprop = rna_idproperty_check(&prop, ptr))) {
2219 RNA_property_int_clamp(ptr, prop, &value);
2220 IDP_Int(idprop) = value;
2221 rna_idproperty_touch(idprop);
2223 else if (iprop->set)
2224 iprop->set(ptr, value);
2225 else if (iprop->set_ex)
2226 iprop->set_ex(ptr, prop, value);
2227 else if (prop->flag & PROP_EDITABLE) {
2228 IDPropertyTemplate val = {0};
2231 RNA_property_int_clamp(ptr, prop, &value);
2235 group = RNA_struct_idprops(ptr, 1);
2237 IDP_AddToGroup(group, IDP_New(IDP_INT, &val, prop->identifier));
2241 void RNA_property_int_get_array(PointerRNA *ptr, PropertyRNA *prop, int *values)
2243 IntPropertyRNA *iprop = (IntPropertyRNA *)prop;
2246 BLI_assert(RNA_property_type(prop) == PROP_INT);
2247 BLI_assert(RNA_property_array_check(prop) != false);
2249 if ((idprop = rna_idproperty_check(&prop, ptr))) {
2250 BLI_assert(idprop->len == RNA_property_array_length(ptr, prop) || (prop->flag & PROP_IDPROPERTY));
2251 if (prop->arraydimension == 0)
2252 values[0] = RNA_property_int_get(ptr, prop);
2254 memcpy(values, IDP_Array(idprop), sizeof(int) * idprop->len);
2256 else if (prop->arraydimension == 0)
2257 values[0] = RNA_property_int_get(ptr, prop);
2258 else if (iprop->getarray)
2259 iprop->getarray(ptr, values);
2260 else if (iprop->getarray_ex)
2261 iprop->getarray_ex(ptr, prop, values);
2262 else if (iprop->defaultarray)
2263 memcpy(values, iprop->defaultarray, sizeof(int) * prop->totarraylength);
2265 memset(values, 0, sizeof(int) * prop->totarraylength);
2268 void RNA_property_int_get_array_range(PointerRNA *ptr, PropertyRNA *prop, int values[2])
2270 const int array_len = RNA_property_array_length(ptr, prop);
2272 if (array_len <= 0) {
2276 else if (array_len == 1) {
2277 RNA_property_int_get_array(ptr, prop, values);
2278 values[1] = values[0];
2285 if (array_len > 32) {
2286 arr = MEM_mallocN(sizeof(int) * array_len, __func__);
2292 RNA_property_int_get_array(ptr, prop, arr);
2293 values[0] = values[1] = arr[0];
2294 for (i = 1; i < array_len; i++) {
2295 values[0] = MIN2(values[0], arr[i]);
2296 values[1] = MAX2(values[1], arr[i]);
2299 if (arr != arr_stack) {
2305 int RNA_property_int_get_index(PointerRNA *ptr, PropertyRNA *prop, int index)
2307 int tmp[RNA_MAX_ARRAY_LENGTH];
2308 int len = rna_ensure_property_array_length(ptr, prop);
2310 BLI_assert(RNA_property_type(prop) == PROP_INT);
2311 BLI_assert(RNA_property_array_check(prop) != false);
2312 BLI_assert(index >= 0);
2313 BLI_assert(index < len);
2315 if (len <= RNA_MAX_ARRAY_LENGTH) {
2316 RNA_property_int_get_array(ptr, prop, tmp);
2320 int *tmparray, value;
2322 tmparray = MEM_mallocN(sizeof(int) * len, __func__);
2323 RNA_property_int_get_array(ptr, prop, tmparray);
2324 value = tmparray[index];
2325 MEM_freeN(tmparray);
2331 void RNA_property_int_set_array(PointerRNA *ptr, PropertyRNA *prop, const int *values)
2333 IntPropertyRNA *iprop = (IntPropertyRNA *)prop;
2336 BLI_assert(RNA_property_type(prop) == PROP_INT);
2337 BLI_assert(RNA_property_array_check(prop) != false);
2339 if ((idprop = rna_idproperty_check(&prop, ptr))) {
2340 BLI_assert(idprop->len == RNA_property_array_length(ptr, prop) || (prop->flag & PROP_IDPROPERTY));
2341 if (prop->arraydimension == 0)
2342 IDP_Int(idprop) = values[0];
2344 memcpy(IDP_Array(idprop), values, sizeof(int) * idprop->len);
2346 rna_idproperty_touch(idprop);
2348 else if (prop->arraydimension == 0)
2349 RNA_property_int_set(ptr, prop, values[0]);
2350 else if (iprop->setarray)
2351 iprop->setarray(ptr, values);
2352 else if (iprop->setarray_ex)
2353 iprop->setarray_ex(ptr, prop, values);
2354 else if (prop->flag & PROP_EDITABLE) {
2355 IDPropertyTemplate val = {0};
2358 /* TODO: RNA_property_int_clamp_array(ptr, prop, &value); */
2360 val.array.len = prop->totarraylength;
2361 val.array.type = IDP_INT;
2363 group = RNA_struct_idprops(ptr, 1);
2365 idprop = IDP_New(IDP_ARRAY, &val, prop->identifier);
2366 IDP_AddToGroup(group, idprop);
2367 memcpy(IDP_Array(idprop), values, sizeof(int) * idprop->len);
2372 void RNA_property_int_set_index(PointerRNA *ptr, PropertyRNA *prop, int index, int value)
2374 int tmp[RNA_MAX_ARRAY_LENGTH];
2375 int len = rna_ensure_property_array_length(ptr, prop);
2377 BLI_assert(RNA_property_type(prop) == PROP_INT);
2378 BLI_assert(RNA_property_array_check(prop) != false);
2379 BLI_assert(index >= 0);
2380 BLI_assert(index < len);
2382 if (len <= RNA_MAX_ARRAY_LENGTH) {
2383 RNA_property_int_get_array(ptr, prop, tmp);
2385 RNA_property_int_set_array(ptr, prop, tmp);
2390 tmparray = MEM_mallocN(sizeof(int) * len, __func__);
2391 RNA_property_int_get_array(ptr, prop, tmparray);
2392 tmparray[index] = value;
2393 RNA_property_int_set_array(ptr, prop, tmparray);
2394 MEM_freeN(tmparray);
2398 int RNA_property_int_get_default(PointerRNA *UNUSED(ptr), PropertyRNA *prop)
2400 IntPropertyRNA *iprop = (IntPropertyRNA *)rna_ensure_property(prop);
2401 return iprop->defaultvalue;
2404 void RNA_property_int_get_default_array(PointerRNA *UNUSED(ptr), PropertyRNA *prop, int *values)
2406 IntPropertyRNA *iprop = (IntPropertyRNA *)rna_ensure_property(prop);
2408 BLI_assert(RNA_property_type(prop) == PROP_INT);
2409 BLI_assert(RNA_property_array_check(prop) != false);
2411 if (prop->arraydimension == 0)
2412 values[0] = iprop->defaultvalue;
2413 else if (iprop->defaultarray)
2414 memcpy(values, iprop->defaultarray, sizeof(int) * prop->totarraylength);
2416 memset(values, 0, sizeof(int) * prop->totarraylength);
2419 int RNA_property_int_get_default_index(PointerRNA *ptr, PropertyRNA *prop, int index)
2421 int tmp[RNA_MAX_ARRAY_LENGTH];
2422 int len = rna_ensure_property_array_length(ptr, prop);
2424 BLI_assert(RNA_property_type(prop) == PROP_INT);
2425 BLI_assert(RNA_property_array_check(prop) != false);
2426 BLI_assert(index >= 0);
2427 BLI_assert(index < prop->totarraylength);
2429 if (len <= RNA_MAX_ARRAY_LENGTH) {
2430 RNA_property_int_get_default_array(ptr, prop, tmp);
2434 int *tmparray, value;
2436 tmparray = MEM_mallocN(sizeof(int) * len, __func__);
2437 RNA_property_int_get_default_array(ptr, prop, tmparray);
2438 value = tmparray[index];
2439 MEM_freeN(tmparray);
2445 float RNA_property_float_get(PointerRNA *ptr, PropertyRNA *prop)
2447 FloatPropertyRNA *fprop = (FloatPropertyRNA *)prop;
2450 BLI_assert(RNA_property_type(prop) == PROP_FLOAT);
2451 BLI_assert(RNA_property_array_check(prop) == false);
2453 if ((idprop = rna_idproperty_check(&prop, ptr))) {
2454 if (idprop->type == IDP_FLOAT)
2455 return IDP_Float(idprop);
2457 return (float)IDP_Double(idprop);
2459 else if (fprop->get)
2460 return fprop->get(ptr);
2461 else if (fprop->get_ex)
2462 return fprop->get_ex(ptr, prop);
2464 return fprop->defaultvalue;
2467 void RNA_property_float_set(PointerRNA *ptr, PropertyRNA *prop, float value)
2469 FloatPropertyRNA *fprop = (FloatPropertyRNA *)prop;
2472 BLI_assert(RNA_property_type(prop) == PROP_FLOAT);
2473 BLI_assert(RNA_property_array_check(prop) == false);
2474 /* useful to check on bad values but set function should clamp */
2475 /* BLI_assert(RNA_property_float_clamp(ptr, prop, &value) == 0); */
2477 if ((idprop = rna_idproperty_check(&prop, ptr))) {
2478 RNA_property_float_clamp(ptr, prop, &value);
2479 if (idprop->type == IDP_FLOAT)
2480 IDP_Float(idprop) = value;
2482 IDP_Double(idprop) = value;
2484 rna_idproperty_touch(idprop);
2486 else if (fprop->set) {
2487 fprop->set(ptr, value);
2489 else if (fprop->set_ex) {
2490 fprop->set_ex(ptr, prop, value);
2492 else if (prop->flag & PROP_EDITABLE) {
2493 IDPropertyTemplate val = {0};
2496 RNA_property_float_clamp(ptr, prop, &value);
2500 group = RNA_struct_idprops(ptr, 1);
2502 IDP_AddToGroup(group, IDP_New(IDP_FLOAT, &val, prop->identifier));
2506 void RNA_property_float_get_array(PointerRNA *ptr, PropertyRNA *prop, float *values)
2508 FloatPropertyRNA *fprop = (FloatPropertyRNA *)prop;
2512 BLI_assert(RNA_property_type(prop) == PROP_FLOAT);
2513 BLI_assert(RNA_property_array_check(prop) != false);
2515 if ((idprop = rna_idproperty_check(&prop, ptr))) {
2516 BLI_assert(idprop->len == RNA_property_array_length(ptr, prop) || (prop->flag & PROP_IDPROPERTY));
2517 if (prop->arraydimension == 0)
2518 values[0] = RNA_property_float_get(ptr, prop);
2519 else if (idprop->subtype == IDP_FLOAT) {
2520 memcpy(values, IDP_Array(idprop), sizeof(float) * idprop->len);
2523 for (i = 0; i < idprop->len; i++)
2524 values[i] = (float)(((double *)IDP_Array(idprop))[i]);
2527 else if (prop->arraydimension == 0)
2528 values[0] = RNA_property_float_get(ptr, prop);
2529 else if (fprop->getarray)
2530 fprop->getarray(ptr, values);
2531 else if (fprop->getarray_ex)
2532 fprop->getarray_ex(ptr, prop, values);
2533 else if (fprop->defaultarray)
2534 memcpy(values, fprop->defaultarray, sizeof(float) * prop->totarraylength);
2536 memset(values, 0, sizeof(float) * prop->totarraylength);
2539 void RNA_property_float_get_array_range(PointerRNA *ptr, PropertyRNA *prop, float values[2])
2541 const int array_len = RNA_property_array_length(ptr, prop);
2543 if (array_len <= 0) {
2547 else if (array_len == 1) {
2548 RNA_property_float_get_array(ptr, prop, values);
2549 values[1] = values[0];
2552 float arr_stack[32];
2556 if (array_len > 32) {
2557 arr = MEM_mallocN(sizeof(float) * array_len, __func__);
2563 RNA_property_float_get_array(ptr, prop, arr);
2564 values[0] = values[1] = arr[0];
2565 for (i = 1; i < array_len; i++) {
2566 values[0] = MIN2(values[0], arr[i]);
2567 values[1] = MAX2(values[1], arr[i]);
2570 if (arr != arr_stack) {
2576 float RNA_property_float_get_index(PointerRNA *ptr, PropertyRNA *prop, int index)
2578 float tmp[RNA_MAX_ARRAY_LENGTH];
2579 int len = rna_ensure_property_array_length(ptr, prop);
2581 BLI_assert(RNA_property_type(prop) == PROP_FLOAT);
2582 BLI_assert(RNA_property_array_check(prop) != false);
2583 BLI_assert(index >= 0);
2584 BLI_assert(index < len);
2586 if (len <= RNA_MAX_ARRAY_LENGTH) {
2587 RNA_property_float_get_array(ptr, prop, tmp);
2591 float *tmparray, value;
2593 tmparray = MEM_mallocN(sizeof(float) * len, __func__);
2594 RNA_property_float_get_array(ptr, prop, tmparray);
2595 value = tmparray[index];
2596 MEM_freeN(tmparray);
2602 void RNA_property_float_set_array(PointerRNA *ptr, PropertyRNA *prop, const float *values)
2604 FloatPropertyRNA *fprop = (FloatPropertyRNA *)prop;
2608 BLI_assert(RNA_property_type(prop) == PROP_FLOAT);
2609 BLI_assert(RNA_property_array_check(prop) != false);
2611 if ((idprop = rna_idproperty_check(&prop, ptr))) {
2612 BLI_assert(idprop->len == RNA_property_array_length(ptr, prop) || (prop->flag & PROP_IDPROPERTY));
2613 if (prop->arraydimension == 0) {
2614 if (idprop->type == IDP_FLOAT)
2615 IDP_Float(idprop) = values[0];
2617 IDP_Double(idprop) = values[0];
2619 else if (idprop->subtype == IDP_FLOAT) {
2620 memcpy(IDP_Array(idprop), values, sizeof(float) * idprop->len);
2623 for (i = 0; i < idprop->len; i++)
2624 ((double *)IDP_Array(idprop))[i] = values[i];
2627 rna_idproperty_touch(idprop);
2629 else if (prop->arraydimension == 0)
2630 RNA_property_float_set(ptr, prop, values[0]);
2631 else if (fprop->setarray) {
2632 fprop->setarray(ptr, values);
2634 else if (fprop->setarray_ex) {
2635 fprop->setarray_ex(ptr, prop, values);
2637 else if (prop->flag & PROP_EDITABLE) {
2638 IDPropertyTemplate val = {0};
2641 /* TODO: RNA_property_float_clamp_array(ptr, prop, &value); */
2643 val.array.len = prop->totarraylength;
2644 val.array.type = IDP_FLOAT;
2646 group = RNA_struct_idprops(ptr, 1);
2648 idprop = IDP_New(IDP_ARRAY, &val, prop->identifier);
2649 IDP_AddToGroup(group, idprop);
2650 memcpy(IDP_Array(idprop), values, sizeof(float) * idprop->len);
2655 void RNA_property_float_set_index(PointerRNA *ptr, PropertyRNA *prop, int index, float value)
2657 float tmp[RNA_MAX_ARRAY_LENGTH];
2658 int len = rna_ensure_property_array_length(ptr, prop);
2660 BLI_assert(RNA_property_type(prop) == PROP_FLOAT);
2661 BLI_assert(RNA_property_array_check(prop) != false);
2662 BLI_assert(index >= 0);
2663 BLI_assert(index < len);
2665 if (len <= RNA_MAX_ARRAY_LENGTH) {
2666 RNA_property_float_get_array(ptr, prop, tmp);
2668 RNA_property_float_set_array(ptr, prop, tmp);
2673 tmparray = MEM_mallocN(sizeof(float) * len, __func__);
2674 RNA_property_float_get_array(ptr, prop, tmparray);
2675 tmparray[index] = value;
2676 RNA_property_float_set_array(ptr, prop, tmparray);
2677 MEM_freeN(tmparray);
2681 float RNA_property_float_get_default(PointerRNA *UNUSED(ptr), PropertyRNA *prop)
2683 FloatPropertyRNA *fprop = (FloatPropertyRNA *)rna_ensure_property(prop);
2685 BLI_assert(RNA_property_type(prop) == PROP_FLOAT);
2686 BLI_assert(RNA_property_array_check(prop) == false);
2688 return fprop->defaultvalue;
2691 void RNA_property_float_get_default_array(PointerRNA *UNUSED(ptr), PropertyRNA *prop, float *values)
2693 FloatPropertyRNA *fprop = (FloatPropertyRNA *)rna_ensure_property(prop);
2695 BLI_assert(RNA_property_type(prop) == PROP_FLOAT);
2696 BLI_assert(RNA_property_array_check(prop) != false);
2698 if (prop->arraydimension == 0)
2699 values[0] = fprop->defaultvalue;
2700 else if (fprop->defaultarray)
2701 memcpy(values, fprop->defaultarray, sizeof(float) * prop->totarraylength);
2703 memset(values, 0, sizeof(float) * prop->totarraylength);
2706 float RNA_property_float_get_default_index(PointerRNA *ptr, PropertyRNA *prop, int index)
2708 float tmp[RNA_MAX_ARRAY_LENGTH];
2709 int len = rna_ensure_property_array_length(ptr, prop);
2711 BLI_assert(RNA_property_type(prop) == PROP_FLOAT);
2712 BLI_assert(RNA_property_array_check(prop) != false);
2713 BLI_assert(index >= 0);
2714 BLI_assert(index < prop->totarraylength);
2716 if (len <= RNA_MAX_ARRAY_LENGTH) {
2717 RNA_property_float_get_default_array(ptr, prop, tmp);
2721 float *tmparray, value;
2723 tmparray = MEM_mallocN(sizeof(float) * len, __func__);
2724 RNA_property_float_get_default_array(ptr, prop, tmparray);
2725 value = tmparray[index];
2726 MEM_freeN(tmparray);
2732 void RNA_property_string_get(PointerRNA *ptr, PropertyRNA *prop, char *value)
2734 StringPropertyRNA *sprop = (StringPropertyRNA *)prop;
2737 BLI_assert(RNA_property_type(prop) == PROP_STRING);
2739 if ((idprop = rna_idproperty_check(&prop, ptr))) {
2740 /* editing bytes is not 100% supported
2741 * since they can contain NIL chars */
2742 if (idprop->subtype == IDP_STRING_SUB_BYTE) {
2743 memcpy(value, IDP_String(idprop), idprop->len);
2744 value[idprop->len] = '\0';
2747 memcpy(value, IDP_String(idprop), idprop->len);
2750 else if (sprop->get) {
2751 sprop->get(ptr, value);
2753 else if (sprop->get_ex) {
2754 sprop->get_ex(ptr, prop, value);
2757 strcpy(value, sprop->defaultvalue);
2761 char *RNA_property_string_get_alloc(PointerRNA *ptr, PropertyRNA *prop,
2762 char *fixedbuf, int fixedlen, int *r_len)
2767 BLI_assert(RNA_property_type(prop) == PROP_STRING);
2769 length = RNA_property_string_length(ptr, prop);
2771 if (length + 1 < fixedlen)
2774 buf = MEM_mallocN(sizeof(char) * (length + 1), "RNA_string_get_alloc");
2777 /* safety check to ensure the string is actually set */
2781 RNA_property_string_get(ptr, prop, buf);
2784 BLI_assert(buf[length] == '\0');
2794 /* this is the length without \0 terminator */
2795 int RNA_property_string_length(PointerRNA *ptr, PropertyRNA *prop)
2797 StringPropertyRNA *sprop = (StringPropertyRNA *)prop;
2800 BLI_assert(RNA_property_type(prop) == PROP_STRING);
2802 if ((idprop = rna_idproperty_check(&prop, ptr))) {
2803 if (idprop->subtype == IDP_STRING_SUB_BYTE) {
2808 /* these _must_ stay in sync */
2809 BLI_assert(strlen(IDP_String(idprop)) == idprop->len - 1);
2811 return idprop->len - 1;
2814 else if (sprop->length)
2815 return sprop->length(ptr);
2816 else if (sprop->length_ex)
2817 return sprop->length_ex(ptr, prop);
2819 return strlen(sprop->defaultvalue);
2822 void RNA_property_string_set(PointerRNA *ptr, PropertyRNA *prop, const char *value)
2824 StringPropertyRNA *sprop = (StringPropertyRNA *)prop;
2827 BLI_assert(RNA_property_type(prop) == PROP_STRING);
2829 if ((idprop = rna_idproperty_check(&prop, ptr))) {
2830 /* both IDP_STRING_SUB_BYTE / IDP_STRING_SUB_UTF8 */
2831 IDP_AssignString(idprop, value, RNA_property_string_maxlength(prop) - 1);
2832 rna_idproperty_touch(idprop);
2834 else if (sprop->set)
2835 sprop->set(ptr, value); /* set function needs to clamp its self */
2836 else if (sprop->set_ex)
2837 sprop->set_ex(ptr, prop, value); /* set function needs to clamp its self */
2838 else if (prop->flag & PROP_EDITABLE) {
2841 group = RNA_struct_idprops(ptr, 1);
2843 IDP_AddToGroup(group, IDP_NewString(value, prop->identifier, RNA_property_string_maxlength(prop)));
2847 void RNA_property_string_get_default(PointerRNA *UNUSED(ptr), PropertyRNA *prop, char *value)
2849 StringPropertyRNA *sprop = (StringPropertyRNA *)rna_ensure_property(prop);
2851 BLI_assert(RNA_property_type(prop) == PROP_STRING);
2853 strcpy(value, sprop->defaultvalue);
2856 char *RNA_property_string_get_default_alloc(PointerRNA *ptr, PropertyRNA *prop, char *fixedbuf, int fixedlen)
2861 BLI_assert(RNA_property_type(prop) == PROP_STRING);
2863 length = RNA_property_string_default_length(ptr, prop);
2865 if (length + 1 < fixedlen)
2868 buf = MEM_callocN(sizeof(char) * (length + 1), "RNA_string_get_alloc");
2870 RNA_property_string_get_default(ptr, prop, buf);
2875 /* this is the length without \0 terminator */
2876 int RNA_property_string_default_length(PointerRNA *UNUSED(ptr), PropertyRNA *prop)
2878 StringPropertyRNA *sprop = (StringPropertyRNA *)prop;
2880 BLI_assert(RNA_property_type(prop) == PROP_STRING);
2882 return strlen(sprop->defaultvalue);
2885 int RNA_property_enum_get(PointerRNA *ptr, PropertyRNA *prop)
2887 EnumPropertyRNA *eprop = (EnumPropertyRNA *)prop;
2890 BLI_assert(RNA_property_type(prop) == PROP_ENUM);
2892 if ((idprop = rna_idproperty_check(&prop, ptr)))
2893 return IDP_Int(idprop);
2894 else if (eprop->get)
2895 return eprop->get(ptr);
2896 else if (eprop->get_ex)
2897 return eprop->get_ex(ptr, prop);
2899 return eprop->defaultvalue;
2902 void RNA_property_enum_set(PointerRNA *ptr, PropertyRNA *prop, int value)
2904 EnumPropertyRNA *eprop = (EnumPropertyRNA *)prop;
2907 BLI_assert(RNA_property_type(prop) == PROP_ENUM);
2909 if ((idprop = rna_idproperty_check(&prop, ptr))) {
2910 IDP_Int(idprop) = value;
2911 rna_idproperty_touch(idprop);
2913 else if (eprop->set) {
2914 eprop->set(ptr, value);
2916 else if (eprop->set_ex) {
2917 eprop->set_ex(ptr, prop, value);
2919 else if (prop->flag & PROP_EDITABLE) {
2920 IDPropertyTemplate val = {0};
2925 group = RNA_struct_idprops(ptr, 1);
2927 IDP_AddToGroup(group, IDP_New(IDP_INT, &val, prop->identifier));
2931 int RNA_property_enum_get_default(PointerRNA *UNUSED(ptr), PropertyRNA *prop)
2933 EnumPropertyRNA *eprop = (EnumPropertyRNA *)rna_ensure_property(prop);
2935 BLI_assert(RNA_property_type(prop) == PROP_ENUM);
2937 return eprop->defaultvalue;
2940 void *RNA_property_enum_py_data_get(PropertyRNA *prop)
2942 EnumPropertyRNA *eprop = (EnumPropertyRNA *)prop;
2944 BLI_assert(RNA_property_type(prop) == PROP_ENUM);
2946 return eprop->py_data;
2950 * Get the value of the item that is \a step items away from \a from_value.
2952 * \param from_value: Item value to start stepping from.
2953 * \param step: Absolute value defines step size, sign defines direction.
2954 * E.g to get the next item, pass 1, for the previous -1.
2956 int RNA_property_enum_step(const bContext *C, PointerRNA *ptr, PropertyRNA *prop, int from_value, int step)
2958 EnumPropertyItem *item_array;
2961 int result_value = from_value;
2963 int single_step = (step < 0) ? -1 : 1;
2966 RNA_property_enum_items((bContext *)C, ptr, prop, &item_array, &totitem, &free);
2967 i = RNA_enum_from_value(item_array, from_value);
2971 i = mod_i(i + single_step, totitem);
2972 if (item_array[i].identifier[0]) {
2973 step_tot += single_step;
2975 } while ((i != i_init) && (step_tot != step));
2978 result_value = item_array[i].value;
2982 MEM_freeN(item_array);
2985 return result_value;
2988 PointerRNA RNA_property_pointer_get(PointerRNA *ptr, PropertyRNA *prop)
2990 PointerPropertyRNA *pprop = (PointerPropertyRNA *)prop;
2993 BLI_assert(RNA_property_type(prop) == PROP_POINTER);
2995 if ((idprop = rna_idproperty_check(&prop, ptr))) {
2996 pprop = (PointerPropertyRNA *)prop;
2998 if (RNA_struct_is_ID(pprop->type)) {
2999 return rna_pointer_inherit_refine(ptr, pprop->type, IDP_Id(idprop));
3002 /* for groups, data is idprop itself */
3004 return rna_pointer_inherit_refine(ptr, pprop->typef(ptr), idprop);
3006 return rna_pointer_inherit_refine(ptr, pprop->type, idprop);
3008 else if (pprop->get) {
3009 return pprop->get(ptr);
3011 else if (prop->flag & PROP_IDPROPERTY) {
3012 /* XXX temporary hack to add it automatically, reading should
3013 * never do any write ops, to ensure thread safety etc .. */
3014 RNA_property_pointer_add(ptr, prop);
3015 return RNA_property_pointer_get(ptr, prop);
3018 return PointerRNA_NULL;
3022 void RNA_property_pointer_set(PointerRNA *ptr, PropertyRNA *prop, PointerRNA ptr_value)
3024 PointerPropertyRNA *pprop = (PointerPropertyRNA *)prop;
3025 BLI_assert(RNA_property_type(prop) == PROP_POINTER);
3028 if (ptr_value.type != NULL && !RNA_struct_is_a(ptr_value.type, pprop->type)) {
3029 printf("%s: expected %s type, not %s.\n", __func__, pprop->type->identifier, ptr_value.type->identifier);
3035 !((prop->flag & PROP_NEVER_NULL) && ptr_value.data == NULL) &&
3036 !((prop->flag & PROP_ID_SELF_CHECK) && ptr->id.data == ptr_value.id.data))
3038 pprop->set(ptr, ptr_value);
3041 else if (prop->flag & PROP_EDITABLE) {
3042 IDPropertyTemplate val = {0};
3045 val.id = ptr_value.data;
3047 group = RNA_struct_idprops(ptr, true);
3049 IDP_ReplaceInGroup(group, IDP_New(IDP_ID, &val, prop->identifier));
3054 PointerRNA RNA_property_pointer_get_default(PointerRNA *UNUSED(ptr), PropertyRNA *UNUSED(prop))
3056 /*PointerPropertyRNA *pprop = (PointerPropertyRNA *)prop; */
3058 /* BLI_assert(RNA_property_type(prop) == PROP_POINTER); */
3060 return PointerRNA_NULL; /* FIXME: there has to be a way... */
3063 void RNA_property_pointer_add(PointerRNA *ptr, PropertyRNA *prop)
3065 /*IDProperty *idprop;*/
3067 BLI_assert(RNA_property_type(prop) == PROP_POINTER);
3069 if ((/*idprop=*/ rna_idproperty_check(&prop, ptr))) {
3070 /* already exists */
3072 else if (prop->flag & PROP_IDPROPERTY) {
3073 IDPropertyTemplate val = {0};
3078 group = RNA_struct_idprops(ptr, 1);
3080 IDP_AddToGroup(group, IDP_New(IDP_GROUP, &val, prop->identifier));
3083 printf("%s %s.%s: only supported for id properties.\n", __func__, ptr->type->identifier, prop->identifier);
3086 void RNA_property_pointer_remove(PointerRNA *ptr, PropertyRNA *prop)
3088 IDProperty *idprop, *group;
3090 BLI_assert(RNA_property_type(prop) == PROP_POINTER);
3092 if ((idprop = rna_idproperty_check(&prop, ptr))) {
3093 group = RNA_struct_idprops(ptr, 0);
3096 IDP_FreeFromGroup(group, idprop);
3100 printf("%s %s.%s: only supported for id properties.\n", __func__, ptr->type->identifier, prop->identifier);
3103 static void rna_property_collection_get_idp(CollectionPropertyIterator *iter)
3105 CollectionPropertyRNA *cprop = (CollectionPropertyRNA *)iter->prop;
3107 iter->ptr.data = rna_iterator_array_get(iter);
3108 iter->ptr.type = cprop->item_type;
3109 rna_pointer_inherit_id(cprop->item_type, &iter->parent, &iter->ptr);
3112 void RNA_property_collection_begin(PointerRNA *ptr, PropertyRNA *prop, CollectionPropertyIterator *iter)
3116 BLI_assert(RNA_property_type(prop) == PROP_COLLECTION);
3118 memset(iter, 0, sizeof(*iter));
3120 if ((idprop = rna_idproperty_check(&prop, ptr)) || (prop->flag & PROP_IDPROPERTY)) {
3121 iter->parent = *ptr;
3125 rna_iterator_array_begin(iter, IDP_IDPArray(idprop), sizeof(IDProperty), idprop->len, 0, NULL);
3127 rna_iterator_array_begin(iter, NULL, sizeof(IDProperty), 0, 0, NULL);
3130 rna_property_collection_get_idp(iter);
3135 CollectionPropertyRNA *cprop = (CollectionPropertyRNA *)prop;
3136 cprop->begin(iter, ptr);
3140 void RNA_property_collection_next(CollectionPropertyIterator *iter)
3142 CollectionPropertyRNA *cprop = (CollectionPropertyRNA *)rna_ensure_property(iter->prop);
3145 rna_iterator_array_next(iter);
3148 rna_property_collection_get_idp(iter);
3154 void RNA_property_collection_skip(CollectionPropertyIterator *iter, int num)
3156 CollectionPropertyRNA *cprop = (CollectionPropertyRNA *)rna_ensure_property(iter->prop);
3159 if (num > 1 && (iter->idprop || (cprop->property.flag_internal & PROP_INTERN_RAW_ARRAY))) {
3160 /* fast skip for array */
3161 ArrayIterator *internal = &iter->internal.array;
3163 if (!internal->skip) {
3164 internal->ptr += internal->itemsize * (num - 1);
3165 iter->valid = (internal->ptr < internal->endptr);
3167 RNA_property_collection_next(iter);
3172 /* slow iteration otherwise */
3173 for (i = 0; i < num && iter->valid; i++)
3174 RNA_property_collection_next(iter);
3177 void RNA_property_collection_end(CollectionPropertyIterator *iter)
3179 CollectionPropertyRNA *cprop = (CollectionPropertyRNA *)rna_ensure_property(iter->prop);
3182 rna_iterator_array_end(iter);
3187 int RNA_property_collection_length(PointerRNA *ptr, PropertyRNA *prop)
3189 CollectionPropertyRNA *cprop = (CollectionPropertyRNA *)prop;
3192 BLI_assert(RNA_property_type(prop) == PROP_COLLECTION);
3194 if ((idprop = rna_idproperty_check(&prop, ptr))) {
3197 else if (cprop->length) {
3198 return cprop->length(ptr);
3201 CollectionPropertyIterator iter;
3204 RNA_property_collection_begin(ptr, prop, &iter);
3205 for (; iter.valid; RNA_property_collection_next(&iter))
3207 RNA_property_collection_end(&iter);
3213 void RNA_property_collection_add(PointerRNA *ptr, PropertyRNA *prop, PointerRNA *r_ptr)
3216 /* CollectionPropertyRNA *cprop = (CollectionPropertyRNA *)prop; */
3218 BLI_assert(RNA_property_type(prop) == PROP_COLLECTION);
3220 if ((idprop = rna_idproperty_check(&prop, ptr))) {
3221 IDPropertyTemplate val = {0};
3224 item = IDP_New(IDP_GROUP, &val, "");
3225 IDP_AppendArray(idprop, item);
3226 /* IDP_FreeProperty(item); *//* IDP_AppendArray does a shallow copy (memcpy), only free memory */
3228 rna_idproperty_touch(idprop);
3230 else if (prop->flag & PROP_IDPROPERTY) {
3231 IDProperty *group, *item;
3232 IDPropertyTemplate val = {0};
3234 group = RNA_struct_idprops(ptr, 1);
3236 idprop = IDP_NewIDPArray(prop->identifier);
3237 IDP_AddToGroup(group, idprop);
3239 item = IDP_New(IDP_GROUP, &val, "");
3240 IDP_AppendArray(idprop, item);
3241 /* IDP_FreeProperty(item); *//* IDP_AppendArray does a shallow copy (memcpy), only free memory */
3246 /* py api calls directly */
3248 else if (cprop->add) {
3249 if (!(cprop->add->flag & FUNC_USE_CONTEXT)) { /* XXX check for this somewhere else */
3250 ParameterList params;
3251 RNA_parameter_list_create(¶ms, ptr, cprop->add);
3252 RNA_function_call(NULL, NULL, ptr, cprop->add, ¶ms);
3253 RNA_parameter_list_free(¶ms);
3258 printf("%s %s.%s: not implemented for this property.\n", __func__, ptr->type->identifier, prop->identifier);
3265 CollectionPropertyRNA *cprop = (CollectionPropertyRNA *)prop;
3267 r_ptr->data = IDP_GetIndexArray(idprop, idprop->len - 1);
3268 r_ptr->type = cprop->item_type;
3269 rna_pointer_inherit_id(NULL, ptr, r_ptr);
3272 memset(r_ptr, 0, sizeof(*r_ptr));
3276 bool RNA_property_collection_remove(PointerRNA *ptr, PropertyRNA *prop, int key)
3279 /* CollectionPropertyRNA *cprop = (CollectionPropertyRNA *)prop; */
3281 BLI_assert(RNA_property_type(prop) == PROP_COLLECTION);
3283 if ((idprop = rna_idproperty_check(&prop, ptr))) {
3284 IDProperty tmp, *array;
3288 array = IDP_IDPArray(idprop);
3290 if (key >= 0 && key < len) {
3291 if (key + 1 < len) {
3292 /* move element to be removed to the back */
3293 memcpy(&tmp, &array[key], sizeof(IDProperty));
3294 memmove(array + key, array + key + 1, sizeof(IDProperty) * (len - (key + 1)));
3295 memcpy(&array[len - 1], &tmp, sizeof(IDProperty));
3298 IDP_ResizeIDPArray(idprop, len - 1);
3303 else if (prop->flag & PROP_IDPROPERTY) {
3307 /* py api calls directly */
3309 else if (cprop->remove) {
3310 if (!(cprop->remove->flag & FUNC_USE_CONTEXT)) { /* XXX check for this somewhere else */
3311 ParameterList params;
3312 RNA_parameter_list_create(¶ms, ptr, cprop->remove);
3313 RNA_function_call(NULL, NULL, ptr, cprop->remove, ¶ms);
3314 RNA_parameter_list_free(¶ms);
3321 printf("%s %s.%s: only supported for id properties.\n", __func__, ptr->type->identifier, prop->identifier);
3328 bool RNA_property_collection_move(PointerRNA *ptr, PropertyRNA *prop, int key, int pos)
3332 BLI_assert(RNA_property_type(prop) == PROP_COLLECTION);
3334 if ((idprop = rna_idproperty_check(&prop, ptr))) {
3335 IDProperty tmp, *array;
3339 array = IDP_IDPArray(idprop);
3341 if (key >= 0 && key < len && pos >= 0 && pos < len && key != pos) {
3342 memcpy(&tmp, &array[key], sizeof(IDProperty));
3344 memmove(array + pos + 1, array + pos, sizeof(IDProperty) * (key - pos));
3346 memmove(array + key, array + key + 1, sizeof(IDProperty) * (pos - key));
3347 memcpy(&array[pos], &tmp, sizeof(IDProperty));
3352 else if (prop->flag & PROP_IDPROPERTY) {
3359 void RNA_property_collection_clear(PointerRNA *ptr, PropertyRNA *prop)
3363 BLI_assert(RNA_property_type(prop) == PROP_COLLECTION);
3365 if ((idprop = rna_idproperty_check(&prop, ptr))) {
3366 IDP_ResizeIDPArray(idprop, 0);
3367 rna_idproperty_touch(idprop);
3371 int RNA_property_collection_lookup_index(PointerRNA *ptr, PropertyRNA *prop, PointerRNA *t_ptr)
3373 CollectionPropertyIterator iter;
3376 BLI_assert(RNA_property_type(prop) == PROP_COLLECTION);
3378 RNA_property_collection_begin(ptr, prop, &iter);
3379 for (index = 0; iter.valid; RNA_property_collection_next(&iter), index++) {
3380 if (iter.ptr.data == t_ptr->data)
3383 RNA_property_collection_end(&iter);
3385 /* did we find it? */
3392 int RNA_property_collection_lookup_int(PointerRNA *ptr, PropertyRNA *prop, int key, PointerRNA *r_ptr)
3394 CollectionPropertyRNA *cprop = (CollectionPropertyRNA *)rna_ensure_property(prop);
3396 BLI_assert(RNA_property_type(prop) == PROP_COLLECTION);
3398 if (cprop->lookupint) {
3399 /* we have a callback defined, use it */
3400 return cprop->lookupint(ptr, key, r_ptr);
3403 /* no callback defined, just iterate and find the nth item */
3404 CollectionPropertyIterator iter;
3407 RNA_property_collection_begin(ptr, prop, &iter);
3408 for (i = 0; iter.valid; RNA_property_collection_next(&iter), i++) {
3414 RNA_property_collection_end(&iter);
3417 memset(r_ptr, 0, sizeof(*r_ptr));