Cleanup: add trailing commas
[blender.git] / source / blender / makesrna / intern / rna_access.c
1 /*
2  * ***** BEGIN GPL LICENSE BLOCK *****
3  *
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.
8  *
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.
13  *
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.
17  *
18  * Contributor(s): Blender Foundation (2008).
19  *
20  * ***** END GPL LICENSE BLOCK *****
21  */
22
23 /** \file blender/makesrna/intern/rna_access.c
24  *  \ingroup RNA
25  */
26
27
28 #include <stdlib.h>
29 #include <stddef.h>
30 #include <string.h>
31 #include <ctype.h>
32
33 #include "MEM_guardedalloc.h"
34
35 #include "DNA_ID.h"
36 #include "DNA_scene_types.h"
37 #include "DNA_constraint_types.h"
38 #include "DNA_modifier_types.h"
39 #include "DNA_windowmanager_types.h"
40
41 #include "BLI_blenlib.h"
42 #include "BLI_utildefines.h"
43 #include "BLI_dynstr.h"
44 #include "BLI_ghash.h"
45 #include "BLI_math.h"
46
47 #ifdef DEBUG_OVERRIDE_TIMEIT
48 #  include "PIL_time_utildefines.h"
49 #endif
50
51 #include "BLF_api.h"
52 #include "BLT_translation.h"
53
54 #include "BKE_animsys.h"
55 #include "BKE_context.h"
56 #include "BKE_idcode.h"
57 #include "BKE_idprop.h"
58 #include "BKE_fcurve.h"
59 #include "BKE_library_override.h"
60 #include "BKE_main.h"
61 #include "BKE_report.h"
62
63 #include "DEG_depsgraph.h"
64
65 #include "RNA_access.h"
66 #include "RNA_define.h"
67 #include "RNA_enum_types.h"
68
69 #include "WM_api.h"
70 #include "WM_message.h"
71
72 /* flush updates */
73 #include "DNA_object_types.h"
74 #include "WM_types.h"
75
76 #include "rna_internal.h"
77
78 const PointerRNA PointerRNA_NULL = {{NULL}};
79
80 /* Init/Exit */
81
82 void RNA_init(void)
83 {
84         StructRNA *srna;
85         PropertyRNA *prop;
86
87         BLENDER_RNA.structs_map = BLI_ghash_str_new_ex(__func__, 2048);
88         BLENDER_RNA.structs_len = 0;
89
90         for (srna = BLENDER_RNA.structs.first; srna; srna = srna->cont.next) {
91                 if (!srna->cont.prophash) {
92                         srna->cont.prophash = BLI_ghash_str_new("RNA_init gh");
93
94                         for (prop = srna->cont.properties.first; prop; prop = prop->next) {
95                                 if (!(prop->flag_internal & PROP_INTERN_BUILTIN)) {
96                                         BLI_ghash_insert(srna->cont.prophash, (void *)prop->identifier, prop);
97                                 }
98                         }
99                 }
100                 BLI_assert(srna->flag & STRUCT_PUBLIC_NAMESPACE);
101                 BLI_ghash_insert(BLENDER_RNA.structs_map, (void *)srna->identifier, srna);
102                 BLENDER_RNA.structs_len += 1;
103         }
104 }
105
106 void RNA_exit(void)
107 {
108         StructRNA *srna;
109
110         RNA_property_update_cache_free();
111
112         for (srna = BLENDER_RNA.structs.first; srna; srna = srna->cont.next) {
113                 if (srna->cont.prophash) {
114                         BLI_ghash_free(srna->cont.prophash, NULL, NULL);
115                         srna->cont.prophash = NULL;
116                 }
117         }
118
119         RNA_free(&BLENDER_RNA);
120 }
121
122 /* Pointer */
123
124 void RNA_main_pointer_create(struct Main *main, PointerRNA *r_ptr)
125 {
126         r_ptr->id.data = NULL;
127         r_ptr->type = &RNA_BlendData;
128         r_ptr->data = main;
129 }
130
131 void RNA_id_pointer_create(ID *id, PointerRNA *r_ptr)
132 {
133         StructRNA *type, *idtype = NULL;
134
135         if (id) {
136                 PointerRNA tmp = {{NULL}};
137                 tmp.data = id;
138                 idtype = rna_ID_refine(&tmp);
139
140                 while (idtype->refine) {
141                         type = idtype->refine(&tmp);
142
143                         if (type == idtype)
144                                 break;
145                         else
146                                 idtype = type;
147                 }
148         }
149
150         r_ptr->id.data = id;
151         r_ptr->type = idtype;
152         r_ptr->data = id;
153 }
154
155 void RNA_pointer_create(ID *id, StructRNA *type, void *data, PointerRNA *r_ptr)
156 {
157 #if 0 /* UNUSED */
158         StructRNA *idtype = NULL;
159
160         if (id) {
161                 PointerRNA tmp = {{0}};
162                 tmp.data = id;
163                 idtype = rna_ID_refine(&tmp);
164         }
165 #endif
166
167         r_ptr->id.data = id;
168         r_ptr->type = type;
169         r_ptr->data = data;
170
171         if (data) {
172                 while (r_ptr->type && r_ptr->type->refine) {
173                         StructRNA *rtype = r_ptr->type->refine(r_ptr);
174
175                         if (rtype == r_ptr->type)
176                                 break;
177                         else
178                                 r_ptr->type = rtype;
179                 }
180         }
181 }
182
183 bool RNA_pointer_is_null(const PointerRNA *ptr)
184 {
185         return !((ptr->data != NULL) && (ptr->id.data != NULL) && (ptr->type != NULL));
186 }
187
188 static void rna_pointer_inherit_id(StructRNA *type, PointerRNA *parent, PointerRNA *ptr)
189 {
190         if (type && type->flag & STRUCT_ID) {
191                 ptr->id.data = ptr->data;
192         }
193         else {
194                 ptr->id.data = parent->id.data;
195         }
196 }
197
198 void RNA_blender_rna_pointer_create(PointerRNA *r_ptr)
199 {
200         r_ptr->id.data = NULL;
201         r_ptr->type = &RNA_BlenderRNA;
202         r_ptr->data = &BLENDER_RNA;
203 }
204
205 PointerRNA rna_pointer_inherit_refine(PointerRNA *ptr, StructRNA *type, void *data)
206 {
207         if (data) {
208                 PointerRNA result;
209                 result.data = data;
210                 result.type = type;
211                 rna_pointer_inherit_id(type, ptr, &result);
212
213                 while (result.type->refine) {
214                         type = result.type->refine(&result);
215
216                         if (type == result.type)
217                                 break;
218                         else
219                                 result.type = type;
220                 }
221                 return result;
222         }
223         else {
224                 return PointerRNA_NULL;
225         }
226 }
227
228 /**/
229 void RNA_pointer_recast(PointerRNA *ptr, PointerRNA *r_ptr)
230 {
231 #if 0 /* works but this case if covered by more general code below. */
232         if (RNA_struct_is_ID(ptr->type)) {
233                 /* simple case */
234                 RNA_id_pointer_create(ptr->id.data, r_ptr);
235         }
236         else
237 #endif
238         {
239                 StructRNA *base;
240                 PointerRNA t_ptr;
241                 *r_ptr = *ptr; /* initialize as the same in case cant recast */
242
243                 for (base = ptr->type->base; base; base = base->base) {
244                         t_ptr = rna_pointer_inherit_refine(ptr, base, ptr->data);
245                         if (t_ptr.type && t_ptr.type != ptr->type) {
246                                 *r_ptr = t_ptr;
247                         }
248                 }
249         }
250 }
251
252 /* ID Properties */
253
254 static void rna_idproperty_touch(IDProperty *idprop)
255 {
256         /* so the property is seen as 'set' by rna */
257         idprop->flag &= ~IDP_FLAG_GHOST;
258 }
259
260 static IDProperty *rna_idproperty_ui_container(PropertyRNA *prop)
261 {
262         IDProperty *idprop;
263
264         for (idprop = ((IDProperty *)prop)->prev; idprop; idprop = idprop->prev) {
265                 if (STREQ(RNA_IDP_UI, idprop->name))
266                         break;
267         }
268
269         if (idprop == NULL) {
270                 for (idprop = ((IDProperty *)prop)->next; idprop; idprop = idprop->next) {
271                         if (STREQ(RNA_IDP_UI, idprop->name))
272                                 break;
273                 }
274         }
275
276         return idprop;
277 }
278
279 /* return a UI local ID prop definition for this prop */
280 static IDProperty *rna_idproperty_ui(PropertyRNA *prop)
281 {
282         IDProperty *idprop = rna_idproperty_ui_container(prop);
283
284         if (idprop) {
285                 return IDP_GetPropertyTypeFromGroup(idprop, ((IDProperty *)prop)->name, IDP_GROUP);
286         }
287
288         return NULL;
289 }
290
291 /* return or create a UI local ID prop definition for this prop */
292 static IDProperty *rna_idproperty_ui_ensure(PointerRNA *ptr, PropertyRNA *prop, bool create)
293 {
294         IDProperty *idprop = rna_idproperty_ui_container(prop);
295         IDPropertyTemplate dummy = { 0 };
296
297         if (idprop == NULL && create) {
298                 IDProperty *props = RNA_struct_idprops(ptr, false);
299
300                 /* Sanity check: props is the actual container of this property. */
301                 if (props != NULL && BLI_findindex(&props->data.group, prop) >= 0) {
302                         idprop = IDP_New(IDP_GROUP, &dummy, RNA_IDP_UI);
303
304                         if (!IDP_AddToGroup(props, idprop)) {
305                                 IDP_FreeProperty(idprop);
306                                 return NULL;
307                         }
308                 }
309         }
310
311         if (idprop) {
312                 const char *name = ((IDProperty *)prop)->name;
313                 IDProperty *rv = IDP_GetPropertyTypeFromGroup(idprop, name, IDP_GROUP);
314
315                 if (rv == NULL && create) {
316                         rv = IDP_New(IDP_GROUP, &dummy, name);
317
318                         if (!IDP_AddToGroup(idprop, rv)) {
319                                 IDP_FreeProperty(rv);
320                                 return NULL;
321                         }
322                 }
323
324                 return rv;
325         }
326
327         return NULL;
328 }
329
330 static bool rna_idproperty_ui_set_default(PointerRNA *ptr, PropertyRNA *prop, const char type, IDPropertyTemplate *value)
331 {
332         BLI_assert(ELEM(type, IDP_INT, IDP_DOUBLE));
333
334         if (prop->magic == RNA_MAGIC) {
335                 return false;
336         }
337
338         /* attempt to get the local ID values */
339         IDProperty *idp_ui = rna_idproperty_ui_ensure(ptr, prop, value != NULL);
340
341         if (idp_ui == NULL) {
342                 return (value == NULL);
343         }
344
345         IDProperty *item = IDP_GetPropertyTypeFromGroup(idp_ui, "default", type);
346
347         if (value == NULL) {
348                 if (item != NULL) {
349                         IDP_RemoveFromGroup(idp_ui, item);
350                 }
351         }
352         else {
353                 if (item != NULL) {
354                         switch (type) {
355                                 case IDP_INT:
356                                         IDP_Int(item) = value->i;
357                                         break;
358                                 case IDP_DOUBLE:
359                                         IDP_Double(item) = value->d;
360                                         break;
361                                 default:
362                                         BLI_assert(false);
363                                         return false;
364                         }
365                 }
366                 else {
367                         item = IDP_New(type, value, "default");
368
369                         if (!IDP_AddToGroup(idp_ui, item)) {
370                                 IDP_FreeProperty(item);
371                                 return false;
372                         }
373                 }
374         }
375
376         return true;
377 }
378
379 IDProperty *RNA_struct_idprops(PointerRNA *ptr, bool create)
380 {
381         StructRNA *type = ptr->type;
382
383         if (type && type->idproperties) {
384                 return type->idproperties(ptr, create);
385         }
386
387         return NULL;
388 }
389
390 bool RNA_struct_idprops_check(StructRNA *srna)
391 {
392         return (srna && srna->idproperties);
393 }
394
395 static IDProperty *rna_idproperty_find(PointerRNA *ptr, const char *name)
396 {
397         IDProperty *group = RNA_struct_idprops(ptr, 0);
398
399         if (group) {
400                 if (group->type == IDP_GROUP) {
401                         return IDP_GetPropertyFromGroup(group, name);
402                 }
403                 else {
404                         /* Not sure why that happens sometimes, with nested properties... */
405                         /* Seems to be actually array prop, name is usually "0"... To be sorted out later. */
406 //                      printf("Got unexpected IDProp container when trying to retrieve %s: %d\n", name, group->type);
407                 }
408         }
409
410         return NULL;
411 }
412
413 static void rna_idproperty_free(PointerRNA *ptr, const char *name)
414 {
415         IDProperty *group = RNA_struct_idprops(ptr, 0);
416
417         if (group) {
418                 IDProperty *idprop = IDP_GetPropertyFromGroup(group, name);
419                 if (idprop) {
420                         IDP_FreeFromGroup(group, idprop);
421                 }
422         }
423 }
424
425 static int rna_ensure_property_array_length(PointerRNA *ptr, PropertyRNA *prop)
426 {
427         if (prop->magic == RNA_MAGIC) {
428                 int arraylen[RNA_MAX_ARRAY_DIMENSION];
429                 return (prop->getlength && ptr->data) ? prop->getlength(ptr, arraylen) : prop->totarraylength;
430         }
431         else {
432                 IDProperty *idprop = (IDProperty *)prop;
433
434                 if (idprop->type == IDP_ARRAY)
435                         return idprop->len;
436                 else
437                         return 0;
438         }
439 }
440
441 static bool rna_ensure_property_array_check(PropertyRNA *prop)
442 {
443         if (prop->magic == RNA_MAGIC) {
444                 return (prop->getlength || prop->totarraylength);
445         }
446         else {
447                 IDProperty *idprop = (IDProperty *)prop;
448
449                 return (idprop->type == IDP_ARRAY);
450         }
451 }
452
453 static void rna_ensure_property_multi_array_length(PointerRNA *ptr, PropertyRNA *prop, int length[])
454 {
455         if (prop->magic == RNA_MAGIC) {
456                 if (prop->getlength)
457                         prop->getlength(ptr, length);
458                 else
459                         memcpy(length, prop->arraylength, prop->arraydimension * sizeof(int));
460         }
461         else {
462                 IDProperty *idprop = (IDProperty *)prop;
463
464                 if (idprop->type == IDP_ARRAY)
465                         length[0] = idprop->len;
466                 else
467                         length[0] = 0;
468         }
469 }
470
471 static bool rna_idproperty_verify_valid(PointerRNA *ptr, PropertyRNA *prop, IDProperty *idprop)
472 {
473         /* this verifies if the idproperty actually matches the property
474          * description and otherwise removes it. this is to ensure that
475          * rna property access is type safe, e.g. if you defined the rna
476          * to have a certain array length you can count on that staying so */
477
478         switch (idprop->type) {
479                 case IDP_IDPARRAY:
480                         if (prop->type != PROP_COLLECTION)
481                                 return false;
482                         break;
483                 case IDP_ARRAY:
484                         if (rna_ensure_property_array_length(ptr, prop) != idprop->len)
485                                 return false;
486
487                         if (idprop->subtype == IDP_FLOAT && prop->type != PROP_FLOAT)
488                                 return false;
489                         if (idprop->subtype == IDP_INT && !ELEM(prop->type, PROP_BOOLEAN, PROP_INT, PROP_ENUM))
490                                 return false;
491
492                         break;
493                 case IDP_INT:
494                         if (!ELEM(prop->type, PROP_BOOLEAN, PROP_INT, PROP_ENUM))
495                                 return false;
496                         break;
497                 case IDP_FLOAT:
498                 case IDP_DOUBLE:
499                         if (prop->type != PROP_FLOAT)
500                                 return false;
501                         break;
502                 case IDP_STRING:
503                         if (prop->type != PROP_STRING)
504                                 return false;
505                         break;
506                 case IDP_GROUP:
507                 case IDP_ID:
508                         if (prop->type != PROP_POINTER)
509                                 return false;
510                         break;
511                 default:
512                         return false;
513         }
514
515         return true;
516 }
517
518 static PropertyRNA *typemap[IDP_NUMTYPES] = {
519         (PropertyRNA *)&rna_PropertyGroupItem_string,
520         (PropertyRNA *)&rna_PropertyGroupItem_int,
521         (PropertyRNA *)&rna_PropertyGroupItem_float,
522         NULL, NULL, NULL,
523         (PropertyRNA *)&rna_PropertyGroupItem_group,
524         (PropertyRNA *)&rna_PropertyGroupItem_id,
525         (PropertyRNA *)&rna_PropertyGroupItem_double,
526         (PropertyRNA *)&rna_PropertyGroupItem_idp_array,
527 };
528
529 static PropertyRNA *arraytypemap[IDP_NUMTYPES] = {
530         NULL, (PropertyRNA *)&rna_PropertyGroupItem_int_array,
531         (PropertyRNA *)&rna_PropertyGroupItem_float_array,
532         NULL, NULL, NULL,
533         (PropertyRNA *)&rna_PropertyGroupItem_collection, NULL,
534         (PropertyRNA *)&rna_PropertyGroupItem_double_array,
535 };
536
537 static void *rna_idproperty_check_ex(PropertyRNA **prop, PointerRNA *ptr, const bool return_rnaprop)
538 {
539         /* This is quite a hack, but avoids some complexity in the API. we
540          * pass IDProperty structs as PropertyRNA pointers to the outside.
541          * We store some bytes in PropertyRNA structs that allows us to
542          * distinguish it from IDProperty structs. If it is an ID property,
543          * we look up an IDP PropertyRNA based on the type, and set the data
544          * pointer to the IDProperty. */
545
546         if ((*prop)->magic == RNA_MAGIC) {
547                 if ((*prop)->flag & PROP_IDPROPERTY) {
548                         IDProperty *idprop = rna_idproperty_find(ptr, (*prop)->identifier);
549
550                         if (idprop && !rna_idproperty_verify_valid(ptr, *prop, idprop)) {
551                                 IDProperty *group = RNA_struct_idprops(ptr, 0);
552
553                                 IDP_FreeFromGroup(group, idprop);
554                                 return NULL;
555                         }
556
557                         return idprop;
558                 }
559                 else {
560                         return return_rnaprop ? *prop : NULL;
561                 }
562         }
563
564         {
565                 IDProperty *idprop = (IDProperty *)(*prop);
566
567                 if (idprop->type == IDP_ARRAY)
568                         *prop = arraytypemap[(int)(idprop->subtype)];
569                 else
570                         *prop = typemap[(int)(idprop->type)];
571
572                 return idprop;
573         }
574 }
575
576 /* This function only returns an IDProperty,
577  * or NULL (in case IDProp could not be found, or prop is a real RNA property). */
578 IDProperty *rna_idproperty_check(PropertyRNA **prop, PointerRNA *ptr)
579 {
580         return rna_idproperty_check_ex(prop, ptr, false);
581 }
582
583 /* This function always return the valid, real data pointer, be it a regular RNA property one, or an IDProperty one. */
584 PropertyRNA *rna_ensure_property_realdata(PropertyRNA **prop, PointerRNA *ptr)
585 {
586         return rna_idproperty_check_ex(prop, ptr, true);
587 }
588
589 static PropertyRNA *rna_ensure_property(PropertyRNA *prop)
590 {
591         /* the quick version if we don't need the idproperty */
592
593         if (prop->magic == RNA_MAGIC)
594                 return prop;
595
596         {
597                 IDProperty *idprop = (IDProperty *)prop;
598
599                 if (idprop->type == IDP_ARRAY)
600                         return arraytypemap[(int)(idprop->subtype)];
601                 else
602                         return typemap[(int)(idprop->type)];
603         }
604 }
605
606 static const char *rna_ensure_property_identifier(const PropertyRNA *prop)
607 {
608         if (prop->magic == RNA_MAGIC)
609                 return prop->identifier;
610         else
611                 return ((const IDProperty *)prop)->name;
612 }
613
614 static const char *rna_ensure_property_description(PropertyRNA *prop)
615 {
616         const char *description = NULL;
617
618         if (prop->magic == RNA_MAGIC)
619                 description = prop->description;
620         else {
621                 /* attempt to get the local ID values */
622                 IDProperty *idp_ui = rna_idproperty_ui(prop);
623
624                 if (idp_ui) {
625                         IDProperty *item = IDP_GetPropertyTypeFromGroup(idp_ui, "description", IDP_STRING);
626                         if (item)
627                                 description = IDP_String(item);
628                 }
629
630                 if (description == NULL)
631                         description = ((IDProperty *)prop)->name;  /* XXX - not correct */
632         }
633
634         return description;
635 }
636
637 static const char *rna_ensure_property_name(const PropertyRNA *prop)
638 {
639         const char *name;
640
641         if (prop->magic == RNA_MAGIC)
642                 name = prop->name;
643         else
644                 name = ((const IDProperty *)prop)->name;
645
646         return name;
647 }
648
649 /* Structs */
650
651 StructRNA *RNA_struct_find(const char *identifier)
652 {
653         return BLI_ghash_lookup(BLENDER_RNA.structs_map, identifier);
654 }
655
656 const char *RNA_struct_identifier(const StructRNA *type)
657 {
658         return type->identifier;
659 }
660
661 const char *RNA_struct_ui_name(const StructRNA *type)
662 {
663         return CTX_IFACE_(type->translation_context, type->name);
664 }
665
666 const char *RNA_struct_ui_name_raw(const StructRNA *type)
667 {
668         return type->name;
669 }
670
671 int RNA_struct_ui_icon(const StructRNA *type)
672 {
673         if (type)
674                 return type->icon;
675         else
676                 return ICON_DOT;
677 }
678
679 const char *RNA_struct_ui_description(const StructRNA *type)
680 {
681         return TIP_(type->description);
682 }
683
684 const char *RNA_struct_ui_description_raw(const StructRNA *type)
685 {
686         return type->description;
687 }
688
689 const char *RNA_struct_translation_context(const StructRNA *type)
690 {
691         return type->translation_context;
692 }
693
694 PropertyRNA *RNA_struct_name_property(const StructRNA *type)
695 {
696         return type->nameproperty;
697 }
698
699 const EnumPropertyItem *RNA_struct_property_tag_defines(const StructRNA *type)
700 {
701         return type->prop_tag_defines;
702 }
703
704 PropertyRNA *RNA_struct_iterator_property(StructRNA *type)
705 {
706         return type->iteratorproperty;
707 }
708
709 StructRNA *RNA_struct_base(StructRNA *type)
710 {
711         return type->base;
712 }
713
714 /**
715  * Use to find the subtype directly below a base-type.
716  *
717  * So if type were `RNA_SpotLIght`, `RNA_struct_base_of(type, &RNA_ID)` would return `&RNA_Light`.
718  */
719 const StructRNA *RNA_struct_base_child_of(const StructRNA *type, const StructRNA *parent_type)
720 {
721         while (type) {
722                 if (type->base == parent_type) {
723                         return type;
724                 }
725                 type = type->base;
726         }
727         return NULL;
728 }
729
730 bool RNA_struct_is_ID(const StructRNA *type)
731 {
732         return (type->flag & STRUCT_ID) != 0;
733 }
734
735 bool RNA_struct_undo_check(const StructRNA *type)
736 {
737         return (type->flag & STRUCT_UNDO) != 0;
738 }
739
740 bool RNA_struct_idprops_register_check(const StructRNA *type)
741 {
742         return (type->flag & STRUCT_NO_IDPROPERTIES) == 0;
743 }
744
745 bool RNA_struct_idprops_datablock_allowed(const StructRNA *type)
746 {
747         return (type->flag & (STRUCT_NO_DATABLOCK_IDPROPERTIES | STRUCT_NO_IDPROPERTIES)) == 0;
748 }
749
750 /**
751  * Whether given type implies datablock usage by IDProperties.
752  * This is used to prevent classes allowed to have IDProperties, but not datablock ones, to indirectly use some
753  * (e.g. by assigning an IDP_GROUP containing some IDP_ID pointers...).
754  */
755 bool RNA_struct_idprops_contains_datablock(const StructRNA *type)
756 {
757         return (type->flag & (STRUCT_CONTAINS_DATABLOCK_IDPROPERTIES | STRUCT_ID)) != 0;
758 }
759
760 /* remove an id-property */
761 bool RNA_struct_idprops_unset(PointerRNA *ptr, const char *identifier)
762 {
763         IDProperty *group = RNA_struct_idprops(ptr, 0);
764
765         if (group) {
766                 IDProperty *idp = IDP_GetPropertyFromGroup(group, identifier);
767                 if (idp) {
768                         IDP_FreeFromGroup(group, idp);
769
770                         return true;
771                 }
772         }
773         return false;
774 }
775
776 bool RNA_struct_is_a(const StructRNA *type, const StructRNA *srna)
777 {
778         const StructRNA *base;
779
780         if (srna == &RNA_AnyType)
781                 return true;
782
783         if (!type)
784                 return false;
785
786         /* ptr->type is always maximally refined */
787         for (base = type; base; base = base->base)
788                 if (base == srna)
789                         return true;
790
791         return false;
792 }
793
794 PropertyRNA *RNA_struct_find_property(PointerRNA *ptr, const char *identifier)
795 {
796         if (identifier[0] == '[' && identifier[1] == '"') { /* "  (dummy comment to avoid confusing some
797                                                                  * function lists in text editors) */
798                 /* id prop lookup, not so common */
799                 PropertyRNA *r_prop = NULL;
800                 PointerRNA r_ptr; /* only support single level props */
801                 if (RNA_path_resolve_property(ptr, identifier, &r_ptr, &r_prop) &&
802                     (r_ptr.type == ptr->type) && (r_ptr.data == ptr->data))
803                 {
804                         return r_prop;
805                 }
806         }
807         else {
808                 /* most common case */
809                 PropertyRNA *iterprop = RNA_struct_iterator_property(ptr->type);
810                 PointerRNA propptr;
811
812                 if (RNA_property_collection_lookup_string(ptr, iterprop, identifier, &propptr))
813                         return propptr.data;
814         }
815
816         return NULL;
817 }
818
819 /* Find the property which uses the given nested struct */
820 static PropertyRNA *RNA_struct_find_nested(PointerRNA *ptr, StructRNA *srna)
821 {
822         PropertyRNA *prop = NULL;
823
824         RNA_STRUCT_BEGIN (ptr, iprop)
825         {
826                 /* This assumes that there can only be one user of this nested struct */
827                 if (RNA_property_pointer_type(ptr, iprop) == srna) {
828                         prop = iprop;
829                         break;
830                 }
831         }
832         RNA_PROP_END;
833
834         return prop;
835 }
836
837 bool RNA_struct_contains_property(PointerRNA *ptr, PropertyRNA *prop_test)
838 {
839         /* note, prop_test could be freed memory, only use for comparison */
840
841         /* validate the RNA is ok */
842         PropertyRNA *iterprop;
843         bool found = false;
844
845         iterprop = RNA_struct_iterator_property(ptr->type);
846
847         RNA_PROP_BEGIN (ptr, itemptr, iterprop)
848         {
849                 /* PropertyRNA *prop = itemptr.data; */
850                 if (prop_test == (PropertyRNA *)itemptr.data) {
851                         found = true;
852                         break;
853                 }
854         }
855         RNA_PROP_END;
856
857         return found;
858 }
859
860 unsigned int RNA_struct_count_properties(StructRNA *srna)
861 {
862         PointerRNA struct_ptr;
863         unsigned int counter = 0;
864
865         RNA_pointer_create(NULL, srna, NULL, &struct_ptr);
866
867         RNA_STRUCT_BEGIN (&struct_ptr, prop)
868         {
869                 counter++;
870                 UNUSED_VARS(prop);
871         }
872         RNA_STRUCT_END;
873
874         return counter;
875 }
876
877 /* low level direct access to type->properties, note this ignores parent classes so should be used with care */
878 const struct ListBase *RNA_struct_type_properties(StructRNA *srna)
879 {
880         return &srna->cont.properties;
881 }
882
883 PropertyRNA *RNA_struct_type_find_property(StructRNA *srna, const char *identifier)
884 {
885         return BLI_findstring_ptr(&srna->cont.properties, identifier, offsetof(PropertyRNA, identifier));
886 }
887
888 FunctionRNA *RNA_struct_find_function(StructRNA *srna, const char *identifier)
889 {
890 #if 1
891         FunctionRNA *func;
892         StructRNA *type;
893         for (type = srna; type; type = type->base) {
894                 func = (FunctionRNA *)BLI_findstring_ptr(&type->functions, identifier, offsetof(FunctionRNA, identifier));
895                 if (func) {
896                         return func;
897                 }
898         }
899         return NULL;
900
901         /* functional but slow */
902 #else
903         PointerRNA tptr;
904         PropertyRNA *iterprop;
905         FunctionRNA *func;
906
907         RNA_pointer_create(NULL, &RNA_Struct, srna, &tptr);
908         iterprop = RNA_struct_find_property(&tptr, "functions");
909
910         func = NULL;
911
912         RNA_PROP_BEGIN (&tptr, funcptr, iterprop)
913         {
914                 if (STREQ(identifier, RNA_function_identifier(funcptr.data))) {
915                         func = funcptr.data;
916                         break;
917                 }
918         }
919         RNA_PROP_END;
920
921         return func;
922 #endif
923 }
924
925 const ListBase *RNA_struct_type_functions(StructRNA *srna)
926 {
927         return &srna->functions;
928 }
929
930 StructRegisterFunc RNA_struct_register(StructRNA *type)
931 {
932         return type->reg;
933 }
934
935 StructUnregisterFunc RNA_struct_unregister(StructRNA *type)
936 {
937         do {
938                 if (type->unreg)
939                         return type->unreg;
940         } while ((type = type->base));
941
942         return NULL;
943 }
944
945 void **RNA_struct_instance(PointerRNA *ptr)
946 {
947         StructRNA *type = ptr->type;
948
949         do {
950                 if (type->instance)
951                         return type->instance(ptr);
952         } while ((type = type->base));
953
954         return NULL;
955 }
956
957 void *RNA_struct_py_type_get(StructRNA *srna)
958 {
959         return srna->py_type;
960 }
961
962 void RNA_struct_py_type_set(StructRNA *srna, void *py_type)
963 {
964         srna->py_type = py_type;
965 }
966
967 void *RNA_struct_blender_type_get(StructRNA *srna)
968 {
969         return srna->blender_type;
970 }
971
972 void RNA_struct_blender_type_set(StructRNA *srna, void *blender_type)
973 {
974         srna->blender_type = blender_type;
975 }
976
977 char *RNA_struct_name_get_alloc(PointerRNA *ptr, char *fixedbuf, int fixedlen, int *r_len)
978 {
979         PropertyRNA *nameprop;
980
981         if (ptr->data && (nameprop = RNA_struct_name_property(ptr->type)))
982                 return RNA_property_string_get_alloc(ptr, nameprop, fixedbuf, fixedlen, r_len);
983
984         return NULL;
985 }
986
987 /**
988  * Use when registering structs with the #STRUCT_PUBLIC_NAMESPACE flag.
989  */
990 bool RNA_struct_available_or_report(ReportList *reports, const char *identifier)
991 {
992         const StructRNA *srna_exists = RNA_struct_find(identifier);
993         if (UNLIKELY(srna_exists != NULL)) {
994                 /* Use comprehensive string construction since this is such a rare occurrence
995                  * and information here may cut down time troubleshooting. */
996                 DynStr *dynstr = BLI_dynstr_new();
997                 BLI_dynstr_appendf(dynstr, "Type identifier '%s' is already in use: '", identifier);
998                 BLI_dynstr_append(dynstr, srna_exists->identifier);
999                 int i = 0;
1000                 if (srna_exists->base) {
1001                         for (const StructRNA *base = srna_exists->base; base; base = base->base) {
1002                                 BLI_dynstr_append(dynstr, "(");
1003                                 BLI_dynstr_append(dynstr, base->identifier);
1004                                 i += 1;
1005                         }
1006                         while (i--) {
1007                                 BLI_dynstr_append(dynstr, ")");
1008                         }
1009                 }
1010                 BLI_dynstr_append(dynstr, "'.");
1011                 char *result = BLI_dynstr_get_cstring(dynstr);
1012                 BLI_dynstr_free(dynstr);
1013                 BKE_report(reports, RPT_ERROR, result);
1014                 MEM_freeN(result);
1015                 return false;
1016         }
1017         else {
1018                 return true;
1019         }
1020 }
1021
1022 bool RNA_struct_bl_idname_ok_or_report(ReportList *reports, const char *identifier, const char *sep)
1023 {
1024         const int len_sep = strlen(sep);
1025         const int len_id = strlen(identifier);
1026         const char *p = strstr(identifier, sep);
1027         /* TODO: make error, for now warning until add-ons update. */
1028 #if 1
1029         const int report_level = RPT_WARNING;
1030         const bool failure = true;
1031 #else
1032         const int report_level = RPT_ERROR;
1033         const bool failure = false;
1034 #endif
1035         if (p == NULL || p == identifier || p + len_sep >= identifier + len_id) {
1036                 BKE_reportf(reports, report_level, "'%s' doesn't contain '%s' with prefix & suffix", identifier, sep);
1037                 return failure;
1038         }
1039
1040         const char *c, *start, *end, *last;
1041         start = identifier;
1042         end = p;
1043         last = end - 1;
1044         for (c = start; c != end; c++) {
1045                 if (((*c >= 'A' && *c <= 'Z') ||
1046                      ((c != start) && (*c >= '0' && *c <= '9')) ||
1047                      ((c != start) && (c != last) && (*c == '_'))) == 0)
1048                 {
1049                         BKE_reportf(reports, report_level, "'%s' doesn't have upper case alpha-numeric prefix", identifier);
1050                         return failure;
1051                 }
1052         }
1053
1054         start = p + len_sep;
1055         end = identifier + len_id;
1056         last = end - 1;
1057         for (c = start; c != end; c++) {
1058                 if (((*c >= 'A' && *c <= 'Z') ||
1059                      (*c >= 'a' && *c <= 'z') ||
1060                      (*c >= '0' && *c <= '9') ||
1061                      ((c != start) && (c != last) && (*c == '_'))) == 0)
1062                 {
1063                         BKE_reportf(reports, report_level, "'%s' doesn't have an alpha-numeric suffix", identifier);
1064                         return failure;
1065                 }
1066         }
1067         return true;
1068 }
1069
1070 /* Property Information */
1071
1072 const char *RNA_property_identifier(const PropertyRNA *prop)
1073 {
1074         return rna_ensure_property_identifier(prop);
1075 }
1076
1077 const char *RNA_property_description(PropertyRNA *prop)
1078 {
1079         return TIP_(rna_ensure_property_description(prop));
1080 }
1081
1082 PropertyType RNA_property_type(PropertyRNA *prop)
1083 {
1084         return rna_ensure_property(prop)->type;
1085 }
1086
1087 PropertySubType RNA_property_subtype(PropertyRNA *prop)
1088 {
1089         return rna_ensure_property(prop)->subtype;
1090 }
1091
1092 PropertyUnit RNA_property_unit(PropertyRNA *prop)
1093 {
1094         return RNA_SUBTYPE_UNIT(rna_ensure_property(prop)->subtype);
1095 }
1096
1097 int RNA_property_flag(PropertyRNA *prop)
1098 {
1099         return rna_ensure_property(prop)->flag;
1100 }
1101
1102 int RNA_property_override_flag(PropertyRNA *prop)
1103 {
1104         return rna_ensure_property(prop)->flag_override;
1105 }
1106
1107 /**
1108  * Get the tags set for \a prop as int bitfield.
1109  * \note Doesn't perform any validity check on the set bits. #RNA_def_property_tags does this
1110  *       in debug builds (to avoid performance issues in non-debug builds), which should be
1111  *       the only way to set tags. Hence, at this point we assume the tag bitfield to be valid.
1112  */
1113 int RNA_property_tags(PropertyRNA *prop)
1114 {
1115         return rna_ensure_property(prop)->tags;
1116 }
1117
1118 bool RNA_property_builtin(PropertyRNA *prop)
1119 {
1120         return (rna_ensure_property(prop)->flag_internal & PROP_INTERN_BUILTIN) != 0;
1121 }
1122
1123 void *RNA_property_py_data_get(PropertyRNA *prop)
1124 {
1125         return prop->py_data;
1126 }
1127
1128 int RNA_property_array_length(PointerRNA *ptr, PropertyRNA *prop)
1129 {
1130         return rna_ensure_property_array_length(ptr, prop);
1131 }
1132
1133 bool RNA_property_array_check(PropertyRNA *prop)
1134 {
1135         return rna_ensure_property_array_check(prop);
1136 }
1137
1138 /* used by BPY to make an array from the python object */
1139 int RNA_property_array_dimension(PointerRNA *ptr, PropertyRNA *prop, int length[])
1140 {
1141         PropertyRNA *rprop = rna_ensure_property(prop);
1142
1143         if (length)
1144                 rna_ensure_property_multi_array_length(ptr, prop, length);
1145
1146         return rprop->arraydimension;
1147 }
1148
1149 /* Return the size of Nth dimension. */
1150 int RNA_property_multi_array_length(PointerRNA *ptr, PropertyRNA *prop, int dim)
1151 {
1152         int len[RNA_MAX_ARRAY_DIMENSION];
1153
1154         rna_ensure_property_multi_array_length(ptr, prop, len);
1155
1156         return len[dim];
1157 }
1158
1159 char RNA_property_array_item_char(PropertyRNA *prop, int index)
1160 {
1161         const char *vectoritem = "XYZW";
1162         const char *quatitem = "WXYZ";
1163         const char *coloritem = "RGBA";
1164         PropertySubType subtype = rna_ensure_property(prop)->subtype;
1165
1166         BLI_assert(index >= 0);
1167
1168         /* get string to use for array index */
1169         if ((index < 4) && ELEM(subtype, PROP_QUATERNION, PROP_AXISANGLE)) {
1170                 return quatitem[index];
1171         }
1172         else if ((index < 4) && ELEM(subtype, PROP_TRANSLATION, PROP_DIRECTION, PROP_XYZ, PROP_XYZ_LENGTH,
1173                                      PROP_EULER, PROP_VELOCITY, PROP_ACCELERATION, PROP_COORDS))
1174         {
1175                 return vectoritem[index];
1176         }
1177         else if ((index < 4) && ELEM(subtype, PROP_COLOR, PROP_COLOR_GAMMA)) {
1178                 return coloritem[index];
1179         }
1180
1181         return '\0';
1182 }
1183
1184 int RNA_property_array_item_index(PropertyRNA *prop, char name)
1185 {
1186         PropertySubType subtype = rna_ensure_property(prop)->subtype;
1187
1188         /* get index based on string name/alias */
1189         /* maybe a function to find char index in string would be better than all the switches */
1190         if (ELEM(subtype, PROP_QUATERNION, PROP_AXISANGLE)) {
1191                 switch (name) {
1192                         case 'w':
1193                                 return 0;
1194                         case 'x':
1195                                 return 1;
1196                         case 'y':
1197                                 return 2;
1198                         case 'z':
1199                                 return 3;
1200                 }
1201         }
1202         else if (ELEM(subtype, PROP_TRANSLATION, PROP_DIRECTION, PROP_XYZ, PROP_XYZ_LENGTH,
1203                        PROP_EULER, PROP_VELOCITY, PROP_ACCELERATION))
1204         {
1205                 switch (name) {
1206                         case 'x':
1207                                 return 0;
1208                         case 'y':
1209                                 return 1;
1210                         case 'z':
1211                                 return 2;
1212                         case 'w':
1213                                 return 3;
1214                 }
1215         }
1216         else if (ELEM(subtype, PROP_COLOR, PROP_COLOR_GAMMA)) {
1217                 switch (name) {
1218                         case 'r':
1219                                 return 0;
1220                         case 'g':
1221                                 return 1;
1222                         case 'b':
1223                                 return 2;
1224                         case 'a':
1225                                 return 3;
1226                 }
1227         }
1228
1229         return -1;
1230 }
1231
1232
1233 void RNA_property_int_range(PointerRNA *ptr, PropertyRNA *prop, int *hardmin, int *hardmax)
1234 {
1235         IntPropertyRNA *iprop = (IntPropertyRNA *)rna_ensure_property(prop);
1236         int softmin, softmax;
1237
1238         if (prop->magic != RNA_MAGIC) {
1239                 /* attempt to get the local ID values */
1240                 IDProperty *idp_ui = rna_idproperty_ui(prop);
1241
1242                 if (idp_ui) {
1243                         IDProperty *item;
1244
1245                         item = IDP_GetPropertyTypeFromGroup(idp_ui, "min", IDP_INT);
1246                         *hardmin = item ? IDP_Int(item) : INT_MIN;
1247
1248                         item = IDP_GetPropertyTypeFromGroup(idp_ui, "max", IDP_INT);
1249                         *hardmax = item ? IDP_Int(item) : INT_MAX;
1250
1251                         return;
1252                 }
1253         }
1254
1255         if (iprop->range) {
1256                 *hardmin = INT_MIN;
1257                 *hardmax = INT_MAX;
1258
1259                 iprop->range(ptr, hardmin, hardmax, &softmin, &softmax);
1260         }
1261         else if (iprop->range_ex) {
1262                 *hardmin = INT_MIN;
1263                 *hardmax = INT_MAX;
1264
1265                 iprop->range_ex(ptr, prop, hardmin, hardmax, &softmin, &softmax);
1266         }
1267         else {
1268                 *hardmin = iprop->hardmin;
1269                 *hardmax = iprop->hardmax;
1270         }
1271 }
1272
1273 void RNA_property_int_ui_range(PointerRNA *ptr, PropertyRNA *prop, int *softmin, int *softmax, int *step)
1274 {
1275         IntPropertyRNA *iprop = (IntPropertyRNA *)rna_ensure_property(prop);
1276         int hardmin, hardmax;
1277
1278         if (prop->magic != RNA_MAGIC) {
1279                 /* attempt to get the local ID values */
1280                 IDProperty *idp_ui = rna_idproperty_ui(prop);
1281
1282                 if (idp_ui) {
1283                         IDProperty *item;
1284
1285                         item = IDP_GetPropertyTypeFromGroup(idp_ui, "soft_min", IDP_INT);
1286                         *softmin = item ? IDP_Int(item) : INT_MIN;
1287
1288                         item = IDP_GetPropertyTypeFromGroup(idp_ui, "soft_max", IDP_INT);
1289                         *softmax = item ? IDP_Int(item) : INT_MAX;
1290
1291                         item = IDP_GetPropertyTypeFromGroup(idp_ui, "step", IDP_INT);
1292                         *step = item ? IDP_Int(item) : 1;
1293
1294                         return;
1295                 }
1296         }
1297
1298         *softmin = iprop->softmin;
1299         *softmax = iprop->softmax;
1300
1301         if (iprop->range) {
1302                 hardmin = INT_MIN;
1303                 hardmax = INT_MAX;
1304
1305                 iprop->range(ptr, &hardmin, &hardmax, softmin, softmax);
1306
1307                 *softmin = max_ii(*softmin, hardmin);
1308                 *softmax = min_ii(*softmax, hardmax);
1309         }
1310         else if (iprop->range_ex) {
1311                 hardmin = INT_MIN;
1312                 hardmax = INT_MAX;
1313
1314                 iprop->range_ex(ptr, prop, &hardmin, &hardmax, softmin, softmax);
1315
1316                 *softmin = max_ii(*softmin, hardmin);
1317                 *softmax = min_ii(*softmax, hardmax);
1318         }
1319
1320         *step = iprop->step;
1321 }
1322
1323 void RNA_property_float_range(PointerRNA *ptr, PropertyRNA *prop, float *hardmin, float *hardmax)
1324 {
1325         FloatPropertyRNA *fprop = (FloatPropertyRNA *)rna_ensure_property(prop);
1326         float softmin, softmax;
1327
1328         if (prop->magic != RNA_MAGIC) {
1329                 /* attempt to get the local ID values */
1330                 IDProperty *idp_ui = rna_idproperty_ui(prop);
1331
1332                 if (idp_ui) {
1333                         IDProperty *item;
1334
1335                         item = IDP_GetPropertyTypeFromGroup(idp_ui, "min", IDP_DOUBLE);
1336                         *hardmin = item ? (float)IDP_Double(item) : -FLT_MAX;
1337
1338                         item = IDP_GetPropertyTypeFromGroup(idp_ui, "max", IDP_DOUBLE);
1339                         *hardmax = item ? (float)IDP_Double(item) : FLT_MAX;
1340
1341                         return;
1342                 }
1343         }
1344
1345         if (fprop->range) {
1346                 *hardmin = -FLT_MAX;
1347                 *hardmax = FLT_MAX;
1348
1349                 fprop->range(ptr, hardmin, hardmax, &softmin, &softmax);
1350         }
1351         else if (fprop->range_ex) {
1352                 *hardmin = -FLT_MAX;
1353                 *hardmax = FLT_MAX;
1354
1355                 fprop->range_ex(ptr, prop, hardmin, hardmax, &softmin, &softmax);
1356         }
1357         else {
1358                 *hardmin = fprop->hardmin;
1359                 *hardmax = fprop->hardmax;
1360         }
1361 }
1362
1363 void RNA_property_float_ui_range(PointerRNA *ptr, PropertyRNA *prop, float *softmin, float *softmax,
1364                                  float *step, float *precision)
1365 {
1366         FloatPropertyRNA *fprop = (FloatPropertyRNA *)rna_ensure_property(prop);
1367         float hardmin, hardmax;
1368
1369         if (prop->magic != RNA_MAGIC) {
1370                 /* attempt to get the local ID values */
1371                 IDProperty *idp_ui = rna_idproperty_ui(prop);
1372
1373                 if (idp_ui) {
1374                         IDProperty *item;
1375
1376                         item = IDP_GetPropertyTypeFromGroup(idp_ui, "soft_min", IDP_DOUBLE);
1377                         *softmin = item ? (float)IDP_Double(item) : -FLT_MAX;
1378
1379                         item = IDP_GetPropertyTypeFromGroup(idp_ui, "soft_max", IDP_DOUBLE);
1380                         *softmax = item ? (float)IDP_Double(item) : FLT_MAX;
1381
1382                         item = IDP_GetPropertyTypeFromGroup(idp_ui, "step", IDP_DOUBLE);
1383                         *step = item ? (float)IDP_Double(item) : 1.0f;
1384
1385                         item = IDP_GetPropertyTypeFromGroup(idp_ui, "precision", IDP_DOUBLE);
1386                         *precision = item ? (float)IDP_Double(item) : 3.0f;
1387
1388                         return;
1389                 }
1390         }
1391
1392         *softmin = fprop->softmin;
1393         *softmax = fprop->softmax;
1394
1395         if (fprop->range) {
1396                 hardmin = -FLT_MAX;
1397                 hardmax = FLT_MAX;
1398
1399                 fprop->range(ptr, &hardmin, &hardmax, softmin, softmax);
1400
1401                 *softmin = max_ff(*softmin, hardmin);
1402                 *softmax = min_ff(*softmax, hardmax);
1403         }
1404         else if (fprop->range_ex) {
1405                 hardmin = -FLT_MAX;
1406                 hardmax = FLT_MAX;
1407
1408                 fprop->range_ex(ptr, prop, &hardmin, &hardmax, softmin, softmax);
1409
1410                 *softmin = max_ff(*softmin, hardmin);
1411                 *softmax = min_ff(*softmax, hardmax);
1412         }
1413
1414         *step = fprop->step;
1415         *precision = (float)fprop->precision;
1416 }
1417
1418 int RNA_property_float_clamp(PointerRNA *ptr, PropertyRNA *prop, float *value)
1419 {
1420         float min, max;
1421
1422         RNA_property_float_range(ptr, prop, &min, &max);
1423
1424         if (*value < min) {
1425                 *value = min;
1426                 return -1;
1427         }
1428         else if (*value > max) {
1429                 *value = max;
1430                 return 1;
1431         }
1432         else {
1433                 return 0;
1434         }
1435 }
1436
1437 int RNA_property_int_clamp(PointerRNA *ptr, PropertyRNA *prop, int *value)
1438 {
1439         int min, max;
1440
1441         RNA_property_int_range(ptr, prop, &min, &max);
1442
1443         if (*value < min) {
1444                 *value = min;
1445                 return -1;
1446         }
1447         else if (*value > max) {
1448                 *value = max;
1449                 return 1;
1450         }
1451         else {
1452                 return 0;
1453         }
1454 }
1455
1456 /* this is the max length including \0 terminator.
1457  * '0' used when their is no maximum */
1458 int RNA_property_string_maxlength(PropertyRNA *prop)
1459 {
1460         StringPropertyRNA *sprop = (StringPropertyRNA *)rna_ensure_property(prop);
1461         return sprop->maxlength;
1462 }
1463
1464 StructRNA *RNA_property_pointer_type(PointerRNA *ptr, PropertyRNA *prop)
1465 {
1466         prop = rna_ensure_property(prop);
1467
1468         if (prop->type == PROP_POINTER) {
1469                 PointerPropertyRNA *pprop = (PointerPropertyRNA *)prop;
1470
1471                 if (pprop->typef)
1472                         return pprop->typef(ptr);
1473                 else if (pprop->type)
1474                         return pprop->type;
1475         }
1476         else if (prop->type == PROP_COLLECTION) {
1477                 CollectionPropertyRNA *cprop = (CollectionPropertyRNA *)prop;
1478
1479                 if (cprop->item_type)
1480                         return cprop->item_type;
1481         }
1482         /* ignore other types, RNA_struct_find_nested calls with unchecked props */
1483
1484         return &RNA_UnknownType;
1485 }
1486
1487 bool RNA_property_pointer_poll(PointerRNA *ptr, PropertyRNA *prop, PointerRNA *value)
1488 {
1489         prop = rna_ensure_property(prop);
1490
1491         if (prop->type == PROP_POINTER) {
1492                 PointerPropertyRNA *pprop = (PointerPropertyRNA *)prop;
1493
1494                 if (pprop->poll) {
1495                         if (rna_idproperty_check(&prop, ptr)) {
1496                                 return ((PropPointerPollFuncPy) pprop->poll)(ptr, *value, prop);
1497                         }
1498                         else {
1499                                 return pprop->poll(ptr, *value);
1500                         }
1501                 }
1502
1503                 return 1;
1504         }
1505
1506         printf("%s: %s is not a pointer property.\n", __func__, prop->identifier);
1507         return 0;
1508 }
1509
1510 void RNA_property_enum_items_ex(
1511         bContext *C, PointerRNA *ptr, PropertyRNA *prop, const bool use_static,
1512         const EnumPropertyItem **r_item, int *r_totitem, bool *r_free)
1513 {
1514         EnumPropertyRNA *eprop = (EnumPropertyRNA *)rna_ensure_property(prop);
1515
1516         *r_free = false;
1517
1518         if (!use_static && eprop->itemf && (C != NULL || (prop->flag & PROP_ENUM_NO_CONTEXT))) {
1519                 const EnumPropertyItem *item;
1520
1521                 if (prop->flag & PROP_ENUM_NO_CONTEXT)
1522                         item = eprop->itemf(NULL, ptr, prop, r_free);
1523                 else
1524                         item = eprop->itemf(C, ptr, prop, r_free);
1525
1526                 /* any callbacks returning NULL should be fixed */
1527                 BLI_assert(item != NULL);
1528
1529                 if (r_totitem) {
1530                         int tot;
1531                         for (tot = 0; item[tot].identifier; tot++) {
1532                                 /* pass */
1533                         }
1534                         *r_totitem = tot;
1535                 }
1536
1537                 *r_item = item;
1538         }
1539         else {
1540                 *r_item = eprop->item;
1541                 if (r_totitem)
1542                         *r_totitem = eprop->totitem;
1543         }
1544 }
1545
1546 void RNA_property_enum_items(
1547         bContext *C, PointerRNA *ptr, PropertyRNA *prop,
1548         const EnumPropertyItem **r_item, int *r_totitem, bool *r_free)
1549 {
1550         RNA_property_enum_items_ex(C, ptr, prop, false, r_item, r_totitem, r_free);
1551 }
1552
1553 #ifdef WITH_INTERNATIONAL
1554 static void property_enum_translate(
1555         PropertyRNA *prop, EnumPropertyItem **r_item, int *r_totitem, bool *r_free)
1556 {
1557         if (!(prop->flag & PROP_ENUM_NO_TRANSLATE)) {
1558                 int i;
1559
1560                 /* Note: Only do those tests once, and then use BLT_pgettext. */
1561                 bool do_iface = BLT_translate_iface();
1562                 bool do_tooltip = BLT_translate_tooltips();
1563                 EnumPropertyItem *nitem;
1564
1565                 if (!(do_iface || do_tooltip))
1566                         return;
1567
1568                 if (*r_free) {
1569                         nitem = *r_item;
1570                 }
1571                 else {
1572                         const EnumPropertyItem *item = *r_item;
1573                         int tot;
1574
1575                         if (r_totitem) {
1576                                 tot = *r_totitem;
1577                         }
1578                         else {
1579                                 /* count */
1580                                 for (tot = 0; item[tot].identifier; tot++) {
1581                                         /* pass */
1582                                 }
1583                         }
1584
1585                         nitem = MEM_mallocN(sizeof(EnumPropertyItem) * (tot + 1), "enum_items_gettexted");
1586                         memcpy(nitem, item, sizeof(EnumPropertyItem) * (tot + 1));
1587
1588                         *r_free = true;
1589                 }
1590
1591                 for (i = 0; nitem[i].identifier; i++) {
1592                         if (nitem[i].name && do_iface) {
1593                                 nitem[i].name = BLT_pgettext(prop->translation_context, nitem[i].name);
1594                         }
1595                         if (nitem[i].description && do_tooltip) {
1596                                 nitem[i].description = BLT_pgettext(NULL, nitem[i].description);
1597                         }
1598                 }
1599
1600                 *r_item = nitem;
1601         }
1602 }
1603 #endif
1604
1605 void RNA_property_enum_items_gettexted(
1606         bContext *C, PointerRNA *ptr, PropertyRNA *prop,
1607         const EnumPropertyItem **r_item, int *r_totitem, bool *r_free)
1608 {
1609         RNA_property_enum_items(C, ptr, prop, r_item, r_totitem, r_free);
1610
1611 #ifdef WITH_INTERNATIONAL
1612         /* Normally dropping 'const' is _not_ ok, in this case it's only modified if we own the memory
1613          * so allow the exception (callers are creating new arrays in this case). */
1614         property_enum_translate(prop, (EnumPropertyItem **)r_item, r_totitem, r_free);
1615 #endif
1616 }
1617
1618 void RNA_property_enum_items_gettexted_all(
1619         bContext *C, PointerRNA *ptr, PropertyRNA *prop,
1620         const EnumPropertyItem **r_item, int *r_totitem, bool *r_free)
1621 {
1622         EnumPropertyRNA *eprop = (EnumPropertyRNA *)rna_ensure_property(prop);
1623         int mem_size = sizeof(EnumPropertyItem) * (eprop->totitem + 1);
1624         /* first return all items */
1625         EnumPropertyItem *item_array = MEM_mallocN(mem_size, "enum_gettext_all");
1626         *r_free = true;
1627         memcpy(item_array, eprop->item, mem_size);
1628
1629         if (r_totitem) {
1630                 *r_totitem = eprop->totitem;
1631         }
1632
1633         if (eprop->itemf && (C != NULL || (prop->flag & PROP_ENUM_NO_CONTEXT))) {
1634                 const EnumPropertyItem *item;
1635                 int i;
1636                 bool free = false;
1637
1638                 if (prop->flag & PROP_ENUM_NO_CONTEXT)
1639                         item = eprop->itemf(NULL, ptr, prop, &free);
1640                 else
1641                         item = eprop->itemf(C, ptr, prop, &free);
1642
1643                 /* any callbacks returning NULL should be fixed */
1644                 BLI_assert(item != NULL);
1645
1646                 for (i = 0; i < eprop->totitem; i++) {
1647                         bool exists = false;
1648                         int i_fixed;
1649
1650                         /* items that do not exist on list are returned, but have their names/identifiers NULLed out */
1651                         for (i_fixed = 0; item[i_fixed].identifier; i_fixed++) {
1652                                 if (STREQ(item[i_fixed].identifier, item_array[i].identifier)) {
1653                                         exists = true;
1654                                         break;
1655                                 }
1656                         }
1657
1658                         if (!exists) {
1659                                 item_array[i].name = NULL;
1660                                 item_array[i].identifier = "";
1661                         }
1662                 }
1663
1664                 if (free) {
1665                         MEM_freeN((void *)item);
1666                 }
1667         }
1668
1669 #ifdef WITH_INTERNATIONAL
1670         property_enum_translate(prop, &item_array, r_totitem, r_free);
1671 #endif
1672         *r_item = item_array;
1673 }
1674
1675 bool RNA_property_enum_value(bContext *C, PointerRNA *ptr, PropertyRNA *prop, const char *identifier, int *r_value)
1676 {
1677         const EnumPropertyItem *item;
1678         bool free;
1679         bool found;
1680
1681         RNA_property_enum_items(C, ptr, prop, &item, NULL, &free);
1682
1683         if (item) {
1684                 const int i = RNA_enum_from_identifier(item, identifier);
1685                 if (i != -1) {
1686                         *r_value = item[i].value;
1687                         found = true;
1688                 }
1689                 else {
1690                         found = false;
1691                 }
1692
1693                 if (free) {
1694                         MEM_freeN((void *)item);
1695                 }
1696         }
1697         else {
1698                 found = false;
1699         }
1700         return found;
1701 }
1702
1703 bool RNA_enum_identifier(const EnumPropertyItem *item, const int value, const char **r_identifier)
1704 {
1705         const int i = RNA_enum_from_value(item, value);
1706         if (i != -1) {
1707                 *r_identifier = item[i].identifier;
1708                 return true;
1709         }
1710         else {
1711                 return false;
1712         }
1713 }
1714
1715 int RNA_enum_bitflag_identifiers(const EnumPropertyItem *item, const int value, const char **r_identifier)
1716 {
1717         int index = 0;
1718         for (; item->identifier; item++) {
1719                 if (item->identifier[0] && item->value & value) {
1720                         r_identifier[index++] = item->identifier;
1721                 }
1722         }
1723         r_identifier[index] = NULL;
1724         return index;
1725 }
1726
1727 bool RNA_enum_name(const EnumPropertyItem *item, const int value, const char **r_name)
1728 {
1729         const int i = RNA_enum_from_value(item, value);
1730         if (i != -1) {
1731                 *r_name = item[i].name;
1732                 return true;
1733         }
1734         else {
1735                 return false;
1736         }
1737 }
1738
1739 bool RNA_enum_description(const EnumPropertyItem *item, const int value, const char **r_description)
1740 {
1741         const int i = RNA_enum_from_value(item, value);
1742         if (i != -1) {
1743                 *r_description = item[i].description;
1744                 return true;
1745         }
1746         else {
1747                 return false;
1748         }
1749 }
1750
1751 int RNA_enum_from_identifier(const EnumPropertyItem *item, const char *identifier)
1752 {
1753         int i = 0;
1754         for (; item->identifier; item++, i++) {
1755                 if (item->identifier[0] && STREQ(item->identifier, identifier)) {
1756                         return i;
1757                 }
1758         }
1759         return -1;
1760 }
1761
1762 /**
1763  * Take care using this with translated enums,
1764  * prefer #RNA_enum_from_identifier where possible.
1765  */
1766 int RNA_enum_from_name(const EnumPropertyItem *item, const char *name)
1767 {
1768         int i = 0;
1769         for (; item->identifier; item++, i++) {
1770                 if (item->identifier[0] && STREQ(item->name, name)) {
1771                         return i;
1772                 }
1773         }
1774         return -1;
1775 }
1776
1777 int RNA_enum_from_value(const EnumPropertyItem *item, const int value)
1778 {
1779         int i = 0;
1780         for (; item->identifier; item++, i++) {
1781                 if (item->identifier[0] && item->value == value) {
1782                         return i;
1783                 }
1784         }
1785         return -1;
1786 }
1787
1788 unsigned int RNA_enum_items_count(const EnumPropertyItem *item)
1789 {
1790         unsigned int i = 0;
1791
1792         while (item->identifier) {
1793                 item++;
1794                 i++;
1795         }
1796
1797         return i;
1798 }
1799
1800 bool RNA_property_enum_identifier(bContext *C, PointerRNA *ptr, PropertyRNA *prop, const int value,
1801                                   const char **identifier)
1802 {
1803         const EnumPropertyItem *item = NULL;
1804         bool free;
1805
1806         RNA_property_enum_items(C, ptr, prop, &item, NULL, &free);
1807         if (item) {
1808                 bool result;
1809                 result = RNA_enum_identifier(item, value, identifier);
1810                 if (free) {
1811                         MEM_freeN((void *)item);
1812                 }
1813                 return result;
1814         }
1815         return false;
1816 }
1817
1818 bool RNA_property_enum_name(bContext *C, PointerRNA *ptr, PropertyRNA *prop, const int value, const char **name)
1819 {
1820         const EnumPropertyItem *item = NULL;
1821         bool free;
1822
1823         RNA_property_enum_items(C, ptr, prop, &item, NULL, &free);
1824         if (item) {
1825                 bool result;
1826                 result = RNA_enum_name(item, value, name);
1827                 if (free) {
1828                         MEM_freeN((void *)item);
1829                 }
1830
1831                 return result;
1832         }
1833         return false;
1834 }
1835
1836 bool RNA_property_enum_name_gettexted(bContext *C, PointerRNA *ptr, PropertyRNA *prop, const int value, const char **name)
1837 {
1838         bool result;
1839
1840         result = RNA_property_enum_name(C, ptr, prop, value, name);
1841
1842         if (result) {
1843                 if (!(prop->flag & PROP_ENUM_NO_TRANSLATE)) {
1844                         if (BLT_translate_iface()) {
1845                                 *name = BLT_pgettext(prop->translation_context, *name);
1846                         }
1847                 }
1848         }
1849
1850         return result;
1851 }
1852
1853 bool RNA_property_enum_item_from_value(
1854         bContext *C, PointerRNA *ptr, PropertyRNA *prop, const int value,
1855         EnumPropertyItem *r_item)
1856 {
1857         const EnumPropertyItem *item = NULL;
1858         bool free;
1859
1860         RNA_property_enum_items(C, ptr, prop, &item, NULL, &free);
1861         if (item) {
1862                 const int i = RNA_enum_from_value(item, value);
1863                 bool result;
1864
1865                 if (i != -1) {
1866                         *r_item = item[i];
1867                         result = true;
1868                 }
1869                 else {
1870                         result = false;
1871                 }
1872
1873                 if (free) {
1874                         MEM_freeN((void *)item);
1875                 }
1876
1877                 return result;
1878         }
1879         return false;
1880 }
1881
1882 bool RNA_property_enum_item_from_value_gettexted(
1883         bContext *C, PointerRNA *ptr, PropertyRNA *prop, const int value,
1884         EnumPropertyItem *r_item)
1885 {
1886         bool result;
1887
1888         result = RNA_property_enum_item_from_value(C, ptr, prop, value, r_item);
1889
1890         if (!(prop->flag & PROP_ENUM_NO_TRANSLATE)) {
1891                 if (BLT_translate_iface()) {
1892                         r_item->name = BLT_pgettext(prop->translation_context, r_item->name);
1893                 }
1894         }
1895
1896         return result;
1897 }
1898
1899 int RNA_property_enum_bitflag_identifiers(bContext *C, PointerRNA *ptr, PropertyRNA *prop, const int value,
1900                                           const char **identifier)
1901 {
1902         const EnumPropertyItem *item = NULL;
1903         bool free;
1904
1905         RNA_property_enum_items(C, ptr, prop, &item, NULL, &free);
1906         if (item) {
1907                 int result;
1908                 result = RNA_enum_bitflag_identifiers(item, value, identifier);
1909                 if (free)
1910                         MEM_freeN((void *)item);
1911
1912                 return result;
1913         }
1914         return 0;
1915 }
1916
1917 const char *RNA_property_ui_name(PropertyRNA *prop)
1918 {
1919         return CTX_IFACE_(prop->translation_context, rna_ensure_property_name(prop));
1920 }
1921
1922 const char *RNA_property_ui_name_raw(PropertyRNA *prop)
1923 {
1924         return rna_ensure_property_name(prop);
1925 }
1926
1927 const char *RNA_property_ui_description(PropertyRNA *prop)
1928 {
1929         return TIP_(rna_ensure_property_description(prop));
1930 }
1931
1932 const char *RNA_property_ui_description_raw(PropertyRNA *prop)
1933 {
1934         return rna_ensure_property_description(prop);
1935 }
1936
1937 const char *RNA_property_translation_context(PropertyRNA *_prop)
1938 {
1939         PropertyRNA *prop = rna_ensure_property(_prop);
1940         return prop->translation_context;
1941 }
1942
1943 int RNA_property_ui_icon(PropertyRNA *prop)
1944 {
1945         return rna_ensure_property(prop)->icon;
1946 }
1947
1948 bool RNA_property_editable(PointerRNA *ptr, PropertyRNA *prop)
1949 {
1950         ID *id = ptr->id.data;
1951         int flag;
1952         const char *dummy_info;
1953
1954         prop = rna_ensure_property(prop);
1955         flag = prop->editable ? prop->editable(ptr, &dummy_info) : prop->flag;
1956
1957         return ((flag & PROP_EDITABLE) &&
1958                 (flag & PROP_REGISTER) == 0 &&
1959                 (!id || ((!ID_IS_LINKED(id) || (prop->flag & PROP_LIB_EXCEPTION)) &&
1960                          (!id->override_static || RNA_property_overridable_get(ptr, prop)))));
1961 }
1962
1963 /**
1964  * Version of #RNA_property_editable that tries to return additional info in \a r_info that can be exposed in UI.
1965  */
1966 bool RNA_property_editable_info(PointerRNA *ptr, PropertyRNA *prop, const char **r_info)
1967 {
1968         ID *id = ptr->id.data;
1969         int flag;
1970
1971         prop = rna_ensure_property(prop);
1972         *r_info = "";
1973
1974         /* get flag */
1975         if (prop->editable) {
1976                 flag = prop->editable(ptr, r_info);
1977         }
1978         else {
1979                 flag = prop->flag;
1980                 if ((flag & PROP_EDITABLE) == 0 || (flag & PROP_REGISTER)) {
1981                         *r_info = N_("This property is for internal use only and can't be edited");
1982                 }
1983         }
1984
1985         /* property from linked data-block */
1986         if (id) {
1987                 if (ID_IS_LINKED(id) && (prop->flag & PROP_LIB_EXCEPTION) == 0) {
1988                         if (!(*r_info)[0]) {
1989                                 *r_info = N_("Can't edit this property from a linked data-block");
1990                         }
1991                         return false;
1992                 }
1993                 if (id->override_static != NULL && !RNA_property_overridable_get(ptr, prop)) {
1994                         if (!(*r_info)[0]) {
1995                                 *r_info = N_("Can't edit this property from an override data-block");
1996                         }
1997                         return false;
1998                 }
1999         }
2000
2001         return ((flag & PROP_EDITABLE) && (flag & PROP_REGISTER) == 0);
2002 }
2003
2004 bool RNA_property_editable_flag(PointerRNA *ptr, PropertyRNA *prop)
2005 {
2006         int flag;
2007         const char *dummy_info;
2008
2009         prop = rna_ensure_property(prop);
2010         flag = prop->editable ? prop->editable(ptr, &dummy_info) : prop->flag;
2011         return (flag & PROP_EDITABLE) != 0;
2012 }
2013
2014 /* same as RNA_property_editable(), except this checks individual items in an array */
2015 bool RNA_property_editable_index(PointerRNA *ptr, PropertyRNA *prop, int index)
2016 {
2017         ID *id;
2018         int flag;
2019
2020         BLI_assert(index >= 0);
2021
2022         prop = rna_ensure_property(prop);
2023
2024         flag = prop->flag;
2025
2026         if (prop->editable) {
2027                 const char *dummy_info;
2028                 flag &= prop->editable(ptr, &dummy_info);
2029         }
2030
2031         if (prop->itemeditable)
2032                 flag &= prop->itemeditable(ptr, index);
2033
2034         id = ptr->id.data;
2035
2036         return (flag & PROP_EDITABLE) && (!id || !ID_IS_LINKED(id) || (prop->flag & PROP_LIB_EXCEPTION));
2037 }
2038
2039 bool RNA_property_animateable(PointerRNA *ptr, PropertyRNA *prop)
2040 {
2041         /* check that base ID-block can support animation data */
2042         if (!id_can_have_animdata(ptr->id.data))
2043                 return false;
2044
2045         prop = rna_ensure_property(prop);
2046
2047         if (!(prop->flag & PROP_ANIMATABLE))
2048                 return false;
2049
2050         return (prop->flag & PROP_EDITABLE) != 0;
2051 }
2052
2053 bool RNA_property_animated(PointerRNA *ptr, PropertyRNA *prop)
2054 {
2055         int len = 1, index;
2056         bool driven, special;
2057
2058         if (!prop)
2059                 return false;
2060
2061         if (RNA_property_array_check(prop))
2062                 len = RNA_property_array_length(ptr, prop);
2063
2064         for (index = 0; index < len; index++) {
2065                 if (rna_get_fcurve(ptr, prop, index, NULL, NULL, &driven, &special))
2066                         return true;
2067         }
2068
2069         return false;
2070 }
2071
2072 /** \note Does not take into account editable status, this has to be checked separately
2073  * (using RNA_property_edtiable_flag() usually). */
2074 bool RNA_property_overridable_get(PointerRNA *ptr, PropertyRNA *prop)
2075 {
2076         if (prop->magic == RNA_MAGIC) {
2077                 /* Special handling for insertions of constraints or modifiers... */
2078                 /* TODO Note We may want to add a more generic system to RNA (like a special property in struct of items)
2079                  * if we get more overrideable collections, for now we can live with those special-cases handling I think. */
2080                 if (RNA_struct_is_a(ptr->type, &RNA_Constraint)) {
2081                         bConstraint *con = ptr->data;
2082                         if (con->flag & CONSTRAINT_STATICOVERRIDE_LOCAL) {
2083                                 return true;
2084                         }
2085                 }
2086                 else if (RNA_struct_is_a(ptr->type, &RNA_Modifier)) {
2087                         ModifierData *mod = ptr->data;
2088                         if (mod->flag & eModifierFlag_StaticOverride_Local) {
2089                                 return true;
2090                         }
2091                 }
2092                 /* If this is a RNA-defined property (real or 'virtual' IDProp), we want to use RNA prop flag. */
2093                 return !(prop->flag_override & PROPOVERRIDE_NO_COMPARISON) && (prop->flag_override & PROPOVERRIDE_OVERRIDABLE_STATIC);
2094         }
2095         else {
2096                 /* If this is a real 'pure' IDProp (aka custom property), we want to use the IDProp flag. */
2097                 return !(prop->flag_override & PROPOVERRIDE_NO_COMPARISON) && (((IDProperty *)prop)->flag & IDP_FLAG_OVERRIDABLE_STATIC);
2098         }
2099 }
2100
2101 /* Should only be used for custom properties */
2102 bool RNA_property_overridable_static_set(PointerRNA *UNUSED(ptr), PropertyRNA *prop, const bool is_overridable)
2103 {
2104         /* Only works for pure custom properties IDProps. */
2105         if (prop->magic != RNA_MAGIC) {
2106                 IDProperty *idprop = (IDProperty *)prop;
2107
2108                 idprop->flag = is_overridable ? (idprop->flag | IDP_FLAG_OVERRIDABLE_STATIC) :
2109                                                 (idprop->flag & ~IDP_FLAG_OVERRIDABLE_STATIC);
2110                 return true;
2111         }
2112
2113         return false;
2114 }
2115
2116
2117 bool RNA_property_overridden(PointerRNA *ptr, PropertyRNA *prop)
2118 {
2119         char *rna_path = RNA_path_from_ID_to_property(ptr, prop);
2120         ID *id = ptr->id.data;
2121
2122         if (rna_path == NULL || id == NULL || id->override_static == NULL) {
2123                 return false;
2124         }
2125
2126         return (BKE_override_static_property_find(id->override_static, rna_path) != NULL);
2127 }
2128
2129 bool RNA_property_comparable(PointerRNA *UNUSED(ptr), PropertyRNA *prop)
2130 {
2131         prop = rna_ensure_property(prop);
2132
2133         return !(prop->flag_override & PROPOVERRIDE_NO_COMPARISON);
2134 }
2135
2136 /* this function is to check if its possible to create a valid path from the ID
2137  * its slow so don't call in a loop */
2138 bool RNA_property_path_from_ID_check(PointerRNA *ptr, PropertyRNA *prop)
2139 {
2140         char *path = RNA_path_from_ID_to_property(ptr, prop);
2141         bool ret = false;
2142
2143         if (path) {
2144                 PointerRNA id_ptr;
2145                 PointerRNA r_ptr;
2146                 PropertyRNA *r_prop;
2147
2148                 RNA_id_pointer_create(ptr->id.data, &id_ptr);
2149                 if (RNA_path_resolve(&id_ptr, path, &r_ptr, &r_prop) == true) {
2150                         ret = (prop == r_prop);
2151                 }
2152                 MEM_freeN(path);
2153         }
2154
2155         return ret;
2156 }
2157
2158
2159 static void rna_property_update(bContext *C, Main *bmain, Scene *scene, PointerRNA *ptr, PropertyRNA *prop)
2160 {
2161         const bool is_rna = (prop->magic == RNA_MAGIC);
2162         prop = rna_ensure_property(prop);
2163
2164         if (is_rna) {
2165                 if (prop->update) {
2166                         /* ideally no context would be needed for update, but there's some
2167                          * parts of the code that need it still, so we have this exception */
2168                         if (prop->flag & PROP_CONTEXT_UPDATE) {
2169                                 if (C) {
2170                                         if ((prop->flag & PROP_CONTEXT_PROPERTY_UPDATE) == PROP_CONTEXT_PROPERTY_UPDATE) {
2171                                                 ((ContextPropUpdateFunc)prop->update)(C, ptr, prop);
2172                                         }
2173                                         else {
2174                                                 ((ContextUpdateFunc)prop->update)(C, ptr);
2175                                         }
2176                                 }
2177                         }
2178                         else
2179                                 prop->update(bmain, scene, ptr);
2180                 }
2181
2182 #if 1
2183                 /* TODO(campbell): Should eventually be replaced entirely by message bus (below)
2184                  * for now keep since COW, bugs are hard to track when we have other missing updates. */
2185                 if (prop->noteflag) {
2186                         WM_main_add_notifier(prop->noteflag, ptr->id.data);
2187                 }
2188 #endif
2189
2190                 /* if C is NULL, we're updating from animation.
2191                  * avoid slow-down from f-curves by not publishing (for now). */
2192                 if (C != NULL) {
2193                         struct wmMsgBus *mbus = CTX_wm_message_bus(C);
2194                         /* we could add NULL check, for now don't */
2195                         WM_msg_publish_rna(mbus, ptr, prop);
2196                 }
2197                 if (ptr->id.data != NULL) {
2198                         const short id_type = GS(((ID *)ptr->id.data)->name);
2199                         if (ID_TYPE_IS_COW(id_type)) {
2200                                 DEG_id_tag_update(ptr->id.data, ID_RECALC_COPY_ON_WRITE);
2201                         }
2202                 }
2203                 /* End message bus. */
2204         }
2205
2206         if (!is_rna || (prop->flag & PROP_IDPROPERTY)) {
2207                 /* WARNING! This is so property drivers update the display!
2208                  * not especially nice  */
2209                 DEG_id_tag_update(ptr->id.data, ID_RECALC_TRANSFORM | ID_RECALC_GEOMETRY);
2210                 WM_main_add_notifier(NC_WINDOW, NULL);
2211                 /* Not nice as well, but the only way to make sure material preview
2212                  * is updated with custom nodes.
2213                  */
2214                 if ((prop->flag & PROP_IDPROPERTY) != 0 &&
2215                     (ptr->id.data != NULL) &&
2216                     (GS(((ID *)ptr->id.data)->name) == ID_NT))
2217                 {
2218                         WM_main_add_notifier(NC_MATERIAL | ND_SHADING, NULL);
2219                 }
2220         }
2221 }
2222
2223 /* must keep in sync with 'rna_property_update'
2224  * note, its possible this returns a false positive in the case of PROP_CONTEXT_UPDATE
2225  * but this isn't likely to be a performance problem. */
2226 bool RNA_property_update_check(PropertyRNA *prop)
2227 {
2228         return (prop->magic != RNA_MAGIC || prop->update || prop->noteflag);
2229 }
2230
2231 void RNA_property_update(bContext *C, PointerRNA *ptr, PropertyRNA *prop)
2232 {
2233         rna_property_update(C, CTX_data_main(C), CTX_data_scene(C), ptr, prop);
2234 }
2235
2236 void RNA_property_update_main(Main *bmain, Scene *scene, PointerRNA *ptr, PropertyRNA *prop)
2237 {
2238         rna_property_update(NULL, bmain, scene, ptr, prop);
2239 }
2240
2241
2242 /* RNA Updates Cache ------------------------ */
2243 /* Overview of RNA Update cache system:
2244  *
2245  * RNA Update calls need to be cached in order to maintain reasonable performance
2246  * of the animation system (i.e. maintaining a somewhat interactive framerate)
2247  * while still allowing updates to be called (necessary in particular for modifier
2248  * property updates to actually work).
2249  *
2250  * The cache is structured with a dual-layer structure
2251  * - L1 = PointerRNA used as key; id.data is used (it should always be defined,
2252  *        and most updates end up using just that anyways)
2253  * - L2 = Update functions to be called on those PointerRNA's
2254  */
2255
2256 /* cache element */
2257 typedef struct tRnaUpdateCacheElem {
2258         struct tRnaUpdateCacheElem *next, *prev;
2259
2260         PointerRNA ptr;     /* L1 key - id as primary, data secondary/ignored? */
2261         ListBase L2Funcs;   /* L2 functions (LinkData<RnaUpdateFuncRef>) */
2262 } tRnaUpdateCacheElem;
2263
2264 /* cache global (tRnaUpdateCacheElem's) - only accessible using these API calls */
2265 static ListBase rna_updates_cache = {NULL, NULL};
2266
2267 /* ........................... */
2268
2269 void RNA_property_update_cache_add(PointerRNA *ptr, PropertyRNA *prop)
2270 {
2271         const bool is_rna = (prop->magic == RNA_MAGIC);
2272         tRnaUpdateCacheElem *uce = NULL;
2273         UpdateFunc fn = NULL;
2274         LinkData *ld;
2275
2276         /* sanity check */
2277         if (NULL == ptr)
2278                 return;
2279
2280         prop = rna_ensure_property(prop);
2281
2282         /* we can only handle update calls with no context args for now (makes animsys updates easier) */
2283         if ((is_rna == false) || (prop->update == NULL) || (prop->flag & PROP_CONTEXT_UPDATE))
2284                 return;
2285         fn = prop->update;
2286
2287         /* find cache element for which key matches... */
2288         for (uce = rna_updates_cache.first; uce; uce = uce->next) {
2289                 /* just match by id only for now, since most update calls that we'll encounter only really care about this */
2290                 /* TODO: later, the cache might need to have some nesting on L1 to cope better
2291                  * with these problems + some tagging to indicate we need this */
2292                 if (uce->ptr.id.data == ptr->id.data)
2293                         break;
2294         }
2295         if (uce == NULL) {
2296                 /* create new instance */
2297                 uce = MEM_callocN(sizeof(tRnaUpdateCacheElem), "tRnaUpdateCacheElem");
2298                 BLI_addtail(&rna_updates_cache, uce);
2299
2300                 /* copy pointer */
2301                 RNA_pointer_create(ptr->id.data, ptr->type, ptr->data, &uce->ptr);
2302         }
2303
2304         /* check on the update func */
2305         for (ld = uce->L2Funcs.first; ld; ld = ld->next) {
2306                 /* stop on match - function already cached */
2307                 if (fn == ld->data)
2308                         return;
2309         }
2310         /* else... if still here, we need to add it */
2311         BLI_addtail(&uce->L2Funcs, BLI_genericNodeN(fn));
2312 }
2313
2314 void RNA_property_update_cache_flush(Main *bmain, Scene *scene)
2315 {
2316         tRnaUpdateCacheElem *uce;
2317
2318         /* TODO: should we check that bmain and scene are valid? The above stuff doesn't! */
2319
2320         /* execute the cached updates */
2321         for (uce = rna_updates_cache.first; uce; uce = uce->next) {
2322                 LinkData *ld;
2323
2324                 for (ld = uce->L2Funcs.first; ld; ld = ld->next) {
2325                         UpdateFunc fn = (UpdateFunc)ld->data;
2326                         fn(bmain, scene, &uce->ptr);
2327                 }
2328         }
2329 }
2330
2331 void RNA_property_update_cache_free(void)
2332 {
2333         tRnaUpdateCacheElem *uce, *ucn;
2334
2335         for (uce = rna_updates_cache.first; uce; uce = ucn) {
2336                 ucn = uce->next;
2337
2338                 /* free L2 cache */
2339                 BLI_freelistN(&uce->L2Funcs);
2340
2341                 /* remove self */
2342                 BLI_freelinkN(&rna_updates_cache, uce);
2343         }
2344 }
2345
2346 /* ---------------------------------------------------------------------- */
2347
2348 /* Property Data */
2349
2350 bool RNA_property_boolean_get(PointerRNA *ptr, PropertyRNA *prop)
2351 {
2352         BoolPropertyRNA *bprop = (BoolPropertyRNA *)prop;
2353         IDProperty *idprop;
2354         bool value;
2355
2356         BLI_assert(RNA_property_type(prop) == PROP_BOOLEAN);
2357         BLI_assert(RNA_property_array_check(prop) == false);
2358
2359         if ((idprop = rna_idproperty_check(&prop, ptr)))
2360                 value = IDP_Int(idprop) != 0;
2361         else if (bprop->get)
2362                 value = bprop->get(ptr);
2363         else if (bprop->get_ex)
2364                 value = bprop->get_ex(ptr, prop);
2365         else
2366                 value = bprop->defaultvalue;
2367
2368         BLI_assert(ELEM(value, false, true));
2369
2370         return value;
2371 }
2372
2373 void RNA_property_boolean_set(PointerRNA *ptr, PropertyRNA *prop, bool value)
2374 {
2375         BoolPropertyRNA *bprop = (BoolPropertyRNA *)prop;
2376         IDProperty *idprop;
2377
2378         BLI_assert(RNA_property_type(prop) == PROP_BOOLEAN);
2379         BLI_assert(RNA_property_array_check(prop) == false);
2380         BLI_assert(ELEM(value, false, true));
2381
2382         /* just in case other values are passed */
2383         BLI_assert(ELEM(value, true, false));
2384
2385         if ((idprop = rna_idproperty_check(&prop, ptr))) {
2386                 IDP_Int(idprop) = (int)value;
2387                 rna_idproperty_touch(idprop);
2388         }
2389         else if (bprop->set) {
2390                 bprop->set(ptr, value);
2391         }
2392         else if (bprop->set_ex) {
2393                 bprop->set_ex(ptr, prop, value);
2394         }
2395         else if (prop->flag & PROP_EDITABLE) {
2396                 IDPropertyTemplate val = {0};
2397                 IDProperty *group;
2398
2399                 val.i = value;
2400
2401                 group = RNA_struct_idprops(ptr, 1);
2402                 if (group)
2403                         IDP_AddToGroup(group, IDP_New(IDP_INT, &val, prop->identifier));
2404         }
2405 }
2406
2407 static void rna_property_boolean_get_default_array_values(BoolPropertyRNA *bprop, bool *values)
2408 {
2409         unsigned int length = bprop->property.totarraylength;
2410
2411         if (bprop->defaultarray) {
2412                 memcpy(values, bprop->defaultarray, sizeof(bool) * length);
2413         }
2414         else {
2415                 for (unsigned int i = 0; i < length; i++) {
2416                         values[i] = bprop->defaultvalue;
2417                 }
2418         }
2419 }
2420
2421 void RNA_property_boolean_get_array(PointerRNA *ptr, PropertyRNA *prop, bool *values)
2422 {
2423         BoolPropertyRNA *bprop = (BoolPropertyRNA *)prop;
2424         IDProperty *idprop;
2425
2426         BLI_assert(RNA_property_type(prop) == PROP_BOOLEAN);
2427         BLI_assert(RNA_property_array_check(prop) != false);
2428
2429         if ((idprop = rna_idproperty_check(&prop, ptr))) {
2430                 if (prop->arraydimension == 0) {
2431                         values[0] = RNA_property_boolean_get(ptr, prop);
2432                 }
2433                 else {
2434                         int *values_src = IDP_Array(idprop);
2435                         for (uint i = 0; i < idprop->len; i++) {
2436                                 values[i] = (bool)values_src[i];
2437                         }
2438                 }
2439         }
2440         else if (prop->arraydimension == 0)
2441                 values[0] = RNA_property_boolean_get(ptr, prop);
2442         else if (bprop->getarray)
2443                 bprop->getarray(ptr, values);
2444         else if (bprop->getarray_ex)
2445                 bprop->getarray_ex(ptr, prop, values);
2446         else
2447                 rna_property_boolean_get_default_array_values(bprop, values);
2448 }
2449
2450 bool RNA_property_boolean_get_index(PointerRNA *ptr, PropertyRNA *prop, int index)
2451 {
2452         bool tmp[RNA_MAX_ARRAY_LENGTH];
2453         int len = rna_ensure_property_array_length(ptr, prop);
2454         bool value;
2455
2456         BLI_assert(RNA_property_type(prop) == PROP_BOOLEAN);
2457         BLI_assert(RNA_property_array_check(prop) != false);
2458         BLI_assert(index >= 0);
2459         BLI_assert(index < len);
2460
2461         if (len <= RNA_MAX_ARRAY_LENGTH) {
2462                 RNA_property_boolean_get_array(ptr, prop, tmp);
2463                 value = tmp[index];
2464         }
2465         else {
2466                 bool *tmparray;
2467
2468                 tmparray = MEM_mallocN(sizeof(bool) * len, __func__);
2469                 RNA_property_boolean_get_array(ptr, prop, tmparray);
2470                 value = tmparray[index];
2471                 MEM_freeN(tmparray);
2472         }
2473
2474         BLI_assert(ELEM(value, false, true));
2475
2476         return value;
2477 }
2478
2479 void RNA_property_boolean_set_array(PointerRNA *ptr, PropertyRNA *prop, const bool *values)
2480 {
2481         BoolPropertyRNA *bprop = (BoolPropertyRNA *)prop;
2482         IDProperty *idprop;
2483
2484         BLI_assert(RNA_property_type(prop) == PROP_BOOLEAN);
2485         BLI_assert(RNA_property_array_check(prop) != false);
2486
2487         if ((idprop = rna_idproperty_check(&prop, ptr))) {
2488                 if (prop->arraydimension == 0) {
2489                         IDP_Int(idprop) = values[0];
2490                 }
2491                 else {
2492                         int *values_dst = IDP_Array(idprop);
2493                         for (uint i = 0; i < idprop->len; i++) {
2494                                 values_dst[i] = (int)values[i];
2495                         }
2496                 }
2497                 rna_idproperty_touch(idprop);
2498         }
2499         else if (prop->arraydimension == 0)
2500                 RNA_property_boolean_set(ptr, prop, values[0]);
2501         else if (bprop->setarray)
2502                 bprop->setarray(ptr, values);
2503         else if (bprop->setarray_ex)
2504                 bprop->setarray_ex(ptr, prop, values);
2505         else if (prop->flag & PROP_EDITABLE) {
2506                 IDPropertyTemplate val = {0};
2507                 IDProperty *group;
2508
2509                 val.array.len = prop->totarraylength;
2510                 val.array.type = IDP_INT;
2511
2512                 group = RNA_struct_idprops(ptr, 1);
2513                 if (group) {
2514                         idprop = IDP_New(IDP_ARRAY, &val, prop->identifier);
2515                         IDP_AddToGroup(group, idprop);
2516                         int *values_dst = IDP_Array(idprop);
2517                         for (uint i = 0; i < idprop->len; i++) {
2518                                 values_dst[i] = (int)values[i];
2519                         }
2520                 }
2521         }
2522 }
2523
2524 void RNA_property_boolean_set_index(PointerRNA *ptr, PropertyRNA *prop, int index, bool value)
2525 {
2526         bool tmp[RNA_MAX_ARRAY_LENGTH];
2527         int len = rna_ensure_property_array_length(ptr, prop);
2528
2529         BLI_assert(RNA_property_type(prop) == PROP_BOOLEAN);
2530         BLI_assert(RNA_property_array_check(prop) != false);
2531         BLI_assert(index >= 0);
2532         BLI_assert(index < len);
2533         BLI_assert(ELEM(value, false, true));
2534
2535         if (len <= RNA_MAX_ARRAY_LENGTH) {
2536                 RNA_property_boolean_get_array(ptr, prop, tmp);
2537                 tmp[index] = value;
2538                 RNA_property_boolean_set_array(ptr, prop, tmp);
2539         }
2540         else {
2541                 bool *tmparray;
2542
2543                 tmparray = MEM_mallocN(sizeof(bool) * len, __func__);
2544                 RNA_property_boolean_get_array(ptr, prop, tmparray);
2545                 tmparray[index] = value;
2546                 RNA_property_boolean_set_array(ptr, prop, tmparray);
2547                 MEM_freeN(tmparray);
2548         }
2549 }
2550
2551 bool RNA_property_boolean_get_default(PointerRNA *UNUSED(ptr), PropertyRNA *prop)
2552 {
2553         BoolPropertyRNA *bprop = (BoolPropertyRNA *)rna_ensure_property(prop);
2554
2555         BLI_assert(RNA_property_type(prop) == PROP_BOOLEAN);
2556         BLI_assert(RNA_property_array_check(prop) == false);
2557         BLI_assert(ELEM(bprop->defaultvalue, false, true));
2558
2559         return bprop->defaultvalue;
2560 }
2561
2562 void RNA_property_boolean_get_default_array(PointerRNA *UNUSED(ptr), PropertyRNA *prop, bool *values)
2563 {
2564         BoolPropertyRNA *bprop = (BoolPropertyRNA *)rna_ensure_property(prop);
2565
2566         BLI_assert(RNA_property_type(prop) == PROP_BOOLEAN);
2567         BLI_assert(RNA_property_array_check(prop) != false);
2568
2569         if (prop->arraydimension == 0)
2570                 values[0] = bprop->defaultvalue;
2571         else
2572                 rna_property_boolean_get_default_array_values(bprop, values);
2573 }
2574
2575 bool RNA_property_boolean_get_default_index(PointerRNA *ptr, PropertyRNA *prop, int index)
2576 {
2577         bool tmp[RNA_MAX_ARRAY_LENGTH];
2578         int len = rna_ensure_property_array_length(ptr, prop);
2579
2580         BLI_assert(RNA_property_type(prop) == PROP_BOOLEAN);
2581         BLI_assert(RNA_property_array_check(prop) != false);
2582         BLI_assert(index >= 0);
2583         BLI_assert(index < prop->totarraylength);
2584
2585         if (len <= RNA_MAX_ARRAY_LENGTH) {
2586                 RNA_property_boolean_get_default_array(ptr, prop, tmp);
2587                 return tmp[index];
2588         }
2589         else {
2590                 bool *tmparray, value;
2591
2592                 tmparray = MEM_mallocN(sizeof(bool) * len, __func__);
2593                 RNA_property_boolean_get_default_array(ptr, prop, tmparray);
2594                 value = tmparray[index];
2595                 MEM_freeN(tmparray);
2596
2597                 return value;
2598         }
2599 }
2600
2601 int RNA_property_int_get(PointerRNA *ptr, PropertyRNA *prop)
2602 {
2603         IntPropertyRNA *iprop = (IntPropertyRNA *)prop;
2604         IDProperty *idprop;
2605
2606         BLI_assert(RNA_property_type(prop) == PROP_INT);
2607         BLI_assert(RNA_property_array_check(prop) == false);
2608
2609         if ((idprop = rna_idproperty_check(&prop, ptr)))
2610                 return IDP_Int(idprop);
2611         else if (iprop->get)
2612                 return iprop->get(ptr);
2613         else if (iprop->get_ex)
2614                 return iprop->get_ex(ptr, prop);
2615         else
2616                 return iprop->defaultvalue;
2617 }
2618
2619 void RNA_property_int_set(PointerRNA *ptr, PropertyRNA *prop, int value)
2620 {
2621         IntPropertyRNA *iprop = (IntPropertyRNA *)prop;
2622         IDProperty *idprop;
2623
2624         BLI_assert(RNA_property_type(prop) == PROP_INT);
2625         BLI_assert(RNA_property_array_check(prop) == false);
2626         /* useful to check on bad values but set function should clamp */
2627         /* BLI_assert(RNA_property_int_clamp(ptr, prop, &value) == 0); */
2628
2629         if ((idprop = rna_idproperty_check(&prop, ptr))) {
2630                 RNA_property_int_clamp(ptr, prop, &value);
2631                 IDP_Int(idprop) = value;
2632                 rna_idproperty_touch(idprop);
2633         }
2634         else if (iprop->set)
2635                 iprop->set(ptr, value);
2636         else if (iprop->set_ex)
2637                 iprop->set_ex(ptr, prop, value);
2638         else if (prop->flag & PROP_EDITABLE) {
2639                 IDPropertyTemplate val = {0};
2640                 IDProperty *group;
2641
2642                 RNA_property_int_clamp(ptr, prop, &value);
2643
2644                 val.i = value;
2645
2646                 group = RNA_struct_idprops(ptr, 1);
2647                 if (group)
2648                         IDP_AddToGroup(group, IDP_New(IDP_INT, &val, prop->identifier));
2649         }
2650 }
2651
2652 static void rna_property_int_get_default_array_values(IntPropertyRNA *iprop, int *values)
2653 {
2654         unsigned int length = iprop->property.totarraylength;
2655
2656         if (iprop->defaultarray) {
2657                 memcpy(values, iprop->defaultarray, sizeof(int) * length);
2658         }
2659         else {
2660                 for (unsigned int i = 0; i < length; i++) {
2661                         values[i] = iprop->defaultvalue;
2662                 }
2663         }
2664 }
2665
2666 void RNA_property_int_get_array(PointerRNA *ptr, PropertyRNA *prop, int *values)
2667 {
2668         IntPropertyRNA *iprop = (IntPropertyRNA *)prop;
2669         IDProperty *idprop;
2670
2671         BLI_assert(RNA_property_type(prop) == PROP_INT);
2672         BLI_assert(RNA_property_array_check(prop) != false);
2673
2674         if ((idprop = rna_idproperty_check(&prop, ptr))) {
2675                 BLI_assert(idprop->len == RNA_property_array_length(ptr, prop) || (prop->flag & PROP_IDPROPERTY));
2676                 if (prop->arraydimension == 0)
2677                         values[0] = RNA_property_int_get(ptr, prop);
2678                 else
2679                         memcpy(values, IDP_Array(idprop), sizeof(int) * idprop->len);
2680         }
2681         else if (prop->arraydimension == 0)
2682                 values[0] = RNA_property_int_get(ptr, prop);
2683         else if (iprop->getarray)
2684                 iprop->getarray(ptr, values);
2685         else if (iprop->getarray_ex)
2686                 iprop->getarray_ex(ptr, prop, values);
2687         else
2688                 rna_property_int_get_default_array_values(iprop, values);
2689 }
2690
2691 void RNA_property_int_get_array_range(PointerRNA *ptr, PropertyRNA *prop, int values[2])
2692 {
2693         const int array_len = RNA_property_array_length(ptr, prop);
2694
2695         if (array_len <= 0) {
2696                 values[0] = 0;
2697                 values[1] = 0;
2698         }
2699         else if (array_len == 1) {
2700                 RNA_property_int_get_array(ptr, prop, values);
2701                 values[1] = values[0];
2702         }
2703         else {
2704                 int arr_stack[32];
2705                 int *arr;
2706                 int i;
2707
2708                 if (array_len > 32) {
2709                         arr = MEM_mallocN(sizeof(int) * array_len, __func__);
2710                 }
2711                 else {
2712                         arr = arr_stack;
2713                 }
2714
2715                 RNA_property_int_get_array(ptr, prop, arr);
2716                 values[0] = values[1] = arr[0];
2717                 for (i = 1; i < array_len; i++) {
2718                         values[0] = MIN2(values[0], arr[i]);
2719                         values[1] = MAX2(values[1], arr[i]);
2720                 }
2721
2722                 if (arr != arr_stack) {
2723                         MEM_freeN(arr);
2724                 }
2725         }
2726 }
2727
2728 int RNA_property_int_get_index(PointerRNA *ptr, PropertyRNA *prop, int index)
2729 {
2730         int tmp[RNA_MAX_ARRAY_LENGTH];
2731         int len = rna_ensure_property_array_length(ptr, prop);
2732
2733         BLI_assert(RNA_property_type(prop) == PROP_INT);
2734         BLI_assert(RNA_property_array_check(prop) != false);
2735         BLI_assert(index >= 0);
2736         BLI_assert(index < len);
2737
2738         if (len <= RNA_MAX_ARRAY_LENGTH) {
2739                 RNA_property_int_get_array(ptr, prop, tmp);
2740                 return tmp[index];
2741         }
2742         else {
2743                 int *tmparray, value;
2744
2745                 tmparray = MEM_mallocN(sizeof(int) * len, __func__);
2746                 RNA_property_int_get_array(ptr, prop, tmparray);
2747                 value = tmparray[index];
2748                 MEM_freeN(tmparray);
2749
2750                 return value;
2751         }
2752 }
2753
2754 void RNA_property_int_set_array(PointerRNA *ptr, PropertyRNA *prop, const int *values)
2755 {
2756         IntPropertyRNA *iprop = (IntPropertyRNA *)prop;
2757         IDProperty *idprop;
2758
2759         BLI_assert(RNA_property_type(prop) == PROP_INT);
2760         BLI_assert(RNA_property_array_check(prop) != false);
2761
2762         if ((idprop = rna_idproperty_check(&prop, ptr))) {
2763                 BLI_assert(idprop->len == RNA_property_array_length(ptr, prop) || (prop->flag & PROP_IDPROPERTY));
2764                 if (prop->arraydimension == 0)
2765                         IDP_Int(idprop) = values[0];
2766                 else
2767                         memcpy(IDP_Array(idprop), values, sizeof(int) * idprop->len);
2768
2769                 rna_idproperty_touch(idprop);
2770         }
2771         else if (prop->arraydimension == 0)
2772                 RNA_property_int_set(ptr, prop, values[0]);
2773         else if (iprop->setarray)
2774                 iprop->setarray(ptr, values);
2775         else if (iprop->setarray_ex)
2776                 iprop->setarray_ex(ptr, prop, values);
2777         else if (prop->flag & PROP_EDITABLE) {
2778                 IDPropertyTemplate val = {0};
2779                 IDProperty *group;
2780
2781                 /* TODO: RNA_property_int_clamp_array(ptr, prop, &value); */
2782
2783                 val.array.len = prop->totarraylength;
2784                 val.array.type = IDP_INT;
2785
2786                 group = RNA_struct_idprops(ptr, 1);
2787                 if (group) {
2788                         idprop = IDP_New(IDP_ARRAY, &val, prop->identifier);
2789                         IDP_AddToGroup(group, idprop);
2790                         memcpy(IDP_Array(idprop), values, sizeof(int) * idprop->len);
2791                 }
2792         }
2793 }
2794
2795 void RNA_property_int_set_index(PointerRNA *ptr, PropertyRNA *prop, int index, int value)
2796 {
2797         int tmp[RNA_MAX_ARRAY_LENGTH];
2798         int len = rna_ensure_property_array_length(ptr, prop);
2799
2800         BLI_assert(RNA_property_type(prop) == PROP_INT);
2801         BLI_assert(RNA_property_array_check(prop) != false);
2802         BLI_assert(index >= 0);
2803         BLI_assert(index < len);
2804
2805         if (len <= RNA_MAX_ARRAY_LENGTH) {
2806                 RNA_property_int_get_array(ptr, prop, tmp);
2807                 tmp[index] = value;
2808                 RNA_property_int_set_array(ptr, prop, tmp);
2809         }
2810         else {
2811                 int *tmparray;
2812
2813                 tmparray = MEM_mallocN(sizeof(int) * len, __func__);
2814                 RNA_property_int_get_array(ptr, prop, tmparray);
2815                 tmparray[index] = value;
2816                 RNA_property_int_set_array(ptr, prop, tmparray);
2817                 MEM_freeN(tmparray);
2818         }
2819 }
2820
2821 int RNA_property_int_get_default(PointerRNA *UNUSED(ptr), PropertyRNA *prop)
2822 {
2823         IntPropertyRNA *iprop = (IntPropertyRNA *)rna_ensure_property(prop);
2824
2825         if (prop->magic != RNA_MAGIC) {
2826                 /* attempt to get the local ID values */
2827                 IDProperty *idp_ui = rna_idproperty_ui(prop);
2828
2829                 if (idp_ui) {
2830                         IDProperty *item;
2831
2832                         item = IDP_GetPropertyTypeFromGroup(idp_ui, "default", IDP_INT);
2833                         return item ? IDP_Int(item) : iprop->defaultvalue;
2834                 }
2835         }
2836
2837         return iprop->defaultvalue;
2838 }
2839
2840 bool RNA_property_int_set_default(PointerRNA *ptr, PropertyRNA *prop, int value)
2841 {
2842         if (value != 0) {
2843                 IDPropertyTemplate val = { .i = value, };
2844                 return rna_idproperty_ui_set_default(ptr, prop, IDP_INT, &val);
2845         }
2846         else {
2847                 return rna_idproperty_ui_set_default(ptr, prop, IDP_INT, NULL);
2848         }
2849 }
2850
2851 void RNA_property_int_get_default_array(PointerRNA *UNUSED(ptr), PropertyRNA *prop, int *values)
2852 {
2853         IntPropertyRNA *iprop = (IntPropertyRNA *)rna_ensure_property(prop);
2854
2855         BLI_assert(RNA_property_type(prop) == PROP_INT);
2856         BLI_assert(RNA_property_array_check(prop) != false);
2857
2858         if (prop->arraydimension == 0)
2859                 values[0] = iprop->defaultvalue;
2860         else
2861                 rna_property_int_get_default_array_values(iprop, values);
2862 }
2863
2864 int RNA_property_int_get_default_index(PointerRNA *ptr, PropertyRNA *prop, int index)
2865 {
2866         int tmp[RNA_MAX_ARRAY_LENGTH];
2867         int len = rna_ensure_property_array_length(ptr, prop);
2868
2869         BLI_assert(RNA_property_type(prop) == PROP_INT);
2870         BLI_assert(RNA_property_array_check(prop) != false);
2871         BLI_assert(index >= 0);
2872         BLI_assert(index < prop->totarraylength);
2873
2874         if (len <= RNA_MAX_ARRAY_LENGTH) {
2875                 RNA_property_int_get_default_array(ptr, prop, tmp);
2876                 return tmp[index];
2877         }
2878         else {
2879                 int *tmparray, value;
2880
2881                 tmparray = MEM_mallocN(sizeof(int) * len, __func__);
2882                 RNA_property_int_get_default_array(ptr, prop, tmparray);
2883                 value = tmparray[index];
2884                 MEM_freeN(tmparray);
2885
2886                 return value;
2887         }
2888 }
2889
2890 float RNA_property_float_get(PointerRNA *ptr, PropertyRNA *prop)
2891 {
2892         FloatPropertyRNA *fprop = (FloatPropertyRNA *)prop;
2893         IDProperty *idprop;
2894
2895         BLI_assert(RNA_property_type(prop) == PROP_FLOAT);
2896         BLI_assert(RNA_property_array_check(prop) == false);
2897
2898         if ((idprop = rna_idproperty_check(&prop, ptr))) {
2899                 if (idprop->type == IDP_FLOAT)
2900                         return IDP_Float(idprop);
2901                 else
2902                         return (float)IDP_Double(idprop);
2903         }
2904         else if (fprop->get)
2905                 return fprop->get(ptr);
2906         else if (fprop->get_ex)
2907                 return fprop->get_ex(ptr, prop);
2908         else
2909                 return fprop->defaultvalue;
2910 }
2911
2912 void RNA_property_float_set(PointerRNA *ptr, PropertyRNA *prop, float value)
2913 {
2914         FloatPropertyRNA *fprop = (FloatPropertyRNA *)prop;
2915         IDProperty *idprop;
2916
2917         BLI_assert(RNA_property_type(prop) == PROP_FLOAT);
2918         BLI_assert(RNA_property_array_check(prop) == false);
2919         /* useful to check on bad values but set function should clamp */
2920         /* BLI_assert(RNA_property_float_clamp(ptr, prop, &value) == 0); */
2921
2922         if ((idprop = rna_idproperty_check(&prop, ptr))) {
2923                 RNA_property_float_clamp(ptr, prop, &value);
2924                 if (idprop->type == IDP_FLOAT)
2925                         IDP_Float(idprop) = value;
2926                 else
2927                         IDP_Double(idprop) = value;
2928
2929                 rna_idproperty_touch(idprop);
2930         }
2931         else if (fprop->set) {
2932                 fprop->set(ptr, value);
2933         }
2934         else if (fprop->set_ex) {
2935                 fprop->set_ex(ptr, prop, value);
2936         }
2937         else if (prop->flag & PROP_EDITABLE) {
2938                 IDPropertyTemplate val = {0};
2939                 IDProperty *group;
2940
2941                 RNA_property_float_clamp(ptr, prop, &value);
2942
2943                 val.f = value;
2944
2945                 group = RNA_struct_idprops(ptr, 1);
2946                 if (group)
2947                         IDP_AddToGroup(group, IDP_New(IDP_FLOAT, &val, prop->identifier));
2948         }
2949 }
2950
2951 static void rna_property_float_get_default_array_values(FloatPropertyRNA *fprop, float *values)
2952 {
2953         unsigned int length = fprop->property.totarraylength;
2954
2955         if (fprop->defaultarray) {
2956                 memcpy(values, fprop->defaultarray, sizeof(float) * length);
2957         }
2958         else {
2959                 for (unsigned int i = 0; i < length; i++) {
2960                         values[i] = fprop->defaultvalue;
2961                 }
2962         }
2963 }
2964
2965 void RNA_property_float_get_array(PointerRNA *ptr, PropertyRNA *prop, float *values)
2966 {
2967         FloatPropertyRNA *fprop = (FloatPropertyRNA *)prop;
2968         IDProperty *idprop;
2969         int i;
2970
2971         BLI_assert(RNA_property_type(prop) == PROP_FLOAT);
2972         BLI_assert(RNA_property_array_check(prop) != false);
2973
2974         if ((idprop = rna_idproperty_check(&prop, ptr))) {
2975                 BLI_assert(idprop->len == RNA_property_array_length(ptr, prop) || (prop->flag & PROP_IDPROPERTY));
2976                 if (prop->arraydimension == 0)
2977                         values[0] = RNA_property_float_get(ptr, prop);
2978                 else if (idprop->subtype == IDP_FLOAT) {
2979                         memcpy(values, IDP_Array(idprop), sizeof(float) * idprop->len);
2980                 }
2981                 else {
2982                         for (i = 0; i < idprop->len; i++)
2983                                 values[i] =  (float)(((double *)IDP_Array(idprop))[i]);
2984                 }
2985         }
2986         else if (prop->arraydimension == 0)
2987                 values[0] = RNA_property_float_get(ptr, prop);
2988         else if (fprop->getarray)
2989                 fprop->getarray(ptr, values);
2990         else if (fprop->getarray_ex)
2991                 fprop->getarray_ex(ptr, prop, values);
2992         else
2993                 rna_property_float_get_default_array_values(fprop, values);
2994 }
2995
2996 void RNA_property_float_get_array_range(PointerRNA *ptr, PropertyRNA *prop, float values[2])
2997 {
2998         const int array_len = RNA_property_array_length(ptr, prop);
2999
3000         if (array_len <= 0) {
3001                 values[0] = 0.0f;
3002                 values[1] = 0.0f;
3003         }
3004         else if (array_len == 1) {
3005                 RNA_property_float_get_array(ptr, prop, values);
3006                 values[1] = values[0];
3007         }
3008         else {
3009                 float arr_stack[32];
3010                 float *arr;
3011                 int i;
3012
3013                 if (array_len > 32) {
3014                         arr = MEM_mallocN(sizeof(float) * array_len, __func__);
3015                 }
3016                 else {
3017                         arr = arr_stack;
3018                 }
3019
3020                 RNA_property_float_get_array(ptr, prop, arr);
3021                 values[0] = values[1] = arr[0];
3022                 for (i = 1; i < array_len; i++) {
3023                         values[0] = MIN2(values[0], arr[i]);
3024                         values[1] = MAX2(values[1], arr[i]);
3025                 }
3026
3027                 if (arr != arr_stack) {
3028                         MEM_freeN(arr);
3029                 }
3030         }
3031 }
3032
3033 float RNA_property_float_get_index(PointerRNA *ptr, PropertyRNA *prop, int index)
3034 {
3035         float tmp[RNA_MAX_ARRAY_LENGTH];
3036         int len = rna_ensure_property_array_length(ptr, prop);
3037
3038         BLI_assert(RNA_property_type(prop) == PROP_FLOAT);
3039         BLI_assert(RNA_property_array_check(prop) != false);
3040         BLI_assert(index >= 0);
3041         BLI_assert(index < len);
3042
3043         if (len <= RNA_MAX_ARRAY_LENGTH) {
3044                 RNA_property_float_get_array(ptr, prop, tmp);
3045                 return tmp[index];
3046         }
3047         else {
3048                 float *tmparray, value;
3049
3050                 tmparray = MEM_mallocN(sizeof(float) * len, __func__);
3051                 RNA_property_float_get_array(ptr, prop, tmparray);
3052                 value = tmparray[index];
3053                 MEM_freeN(tmparray);
3054
3055                 return value;
3056         }
3057 }
3058
3059 void RNA_property_float_set_array(PointerRNA *ptr, PropertyRNA *prop, const float *values)
3060 {
3061         FloatPropertyRNA *fprop = (FloatPropertyRNA *)prop;
3062         IDProperty *idprop;
3063         int i;
3064
3065         BLI_assert(RNA_property_type(prop) == PROP_FLOAT);
3066         BLI_assert(RNA_property_array_check(prop) != false);
3067
3068         if ((idprop = rna_idproperty_check(&prop, ptr))) {
3069                 BLI_assert(idprop->len == RNA_property_array_length(ptr, prop) || (prop->flag & PROP_IDPROPERTY));
3070                 if (prop->arraydimension == 0) {
3071                         if (idprop->type == IDP_FLOAT)
3072                                 IDP_Float(idprop) = values[0];
3073                         else
3074                                 IDP_Double(idprop) = values[0];
3075                 }
3076                 else if (idprop->subtype == IDP_FLOAT) {
3077                         memcpy(IDP_Array(idprop), values, sizeof(float) * idprop->len);
3078                 }
3079                 else {
3080                         for (i = 0; i < idprop->len; i++)
3081                                 ((double *)IDP_Array(idprop))[i] = values[i];
3082                 }
3083
3084                 rna_idproperty_touch(idprop);
3085         }
3086         else if (prop->arraydimension == 0)
3087                 RNA_property_float_set(ptr, prop, values[0]);
3088         else if (fprop->setarray) {
3089                 fprop->setarray(ptr, values);
3090         }
3091         else if (fprop->setarray_ex) {
3092                 fprop->setarray_ex(ptr, prop, values);
3093         }
3094         else if (prop->flag & PROP_EDITABLE) {
3095                 IDPropertyTemplate val = {0};
3096                 IDProperty *group;
3097
3098                 /* TODO: RNA_property_float_clamp_array(ptr, prop, &value); */
3099
3100                 val.array.len = prop->totarraylength;
3101                 val.array.type = IDP_FLOAT;
3102
3103                 group = RNA_struct_idprops(ptr, 1);
3104                 if (group) {
3105                         idprop = IDP_New(IDP_ARRAY, &val, prop->identifier);
3106                         IDP_AddToGroup(group, idprop);
3107                         memcpy(IDP_Array(idprop), values, sizeof(float) * idprop->len);
3108                 }
3109         }
3110 }
3111
3112 void RNA_property_float_set_index(PointerRNA *ptr, PropertyRNA *prop, int index, float value)
3113 {
3114         float tmp[RNA_MAX_ARRAY_LENGTH];
3115         int len = rna_ensure_property_array_length(ptr, prop);
3116
3117         BLI_assert(RNA_property_type(prop) == PROP_FLOAT);
3118         BLI_assert(RNA_property_array_check(prop) != false);
3119         BLI_assert(index >= 0);
3120         BLI_assert(index < len);
3121
3122         if (len <= RNA_MAX_ARRAY_LENGTH) {
3123                 RNA_property_float_get_array(ptr, prop, tmp);
3124                 tmp[index] = value;
3125                 RNA_property_float_set_array(ptr, prop, tmp);
3126         }
3127         else {
3128                 float *tmparray;
3129
3130                 tmparray = MEM_mallocN(sizeof(float) * len, __func__);
3131                 RNA_property_float_get_array(ptr, prop, tmparray);
3132                 tmparray[index] = value;
3133                 RNA_property_float_set_array(ptr, prop, tmparray);
3134                 MEM_freeN(tmparray);
3135         }
3136 }
3137
3138 float RNA_property_float_get_default(PointerRNA *UNUSED(ptr), PropertyRNA *prop)
3139 {
3140         FloatPropertyRNA *fprop = (FloatPropertyRNA *)rna_ensure_property(prop);
3141
3142         BLI_assert(RNA_property_type(prop) == PROP_FLOAT);
3143         BLI_assert(RNA_property_array_check(prop) == false);
3144
3145         if (prop->magic != RNA_MAGIC) {
3146                 /* attempt to get the local ID values */
3147                 IDProperty *idp_ui = rna_idproperty_ui(prop);
3148
3149                 if (idp_ui) {
3150                         IDProperty *item;
3151
3152                         item = IDP_GetPropertyTypeFromGroup(idp_ui, "default", IDP_DOUBLE);
3153                         return item ? IDP_Double(item) : fprop->defaultvalue;
3154                 }
3155         }
3156
3157         return fprop->defaultvalue;
3158 }
3159
3160 bool RNA_property_float_set_default(PointerRNA *ptr, PropertyRNA *prop, float value)
3161 {
3162         if (value != 0) {
3163                 IDPropertyTemplate val = { .d = value, };
3164                 return rna_idproperty_ui_set_default(ptr, prop, IDP_DOUBLE, &val);
3165         }
3166         else {
3167                 return rna_idproperty_ui_set_default(ptr, prop, IDP_DOUBLE, NULL);
3168         }
3169 }
3170
3171 void RNA_property_float_get_default_array(PointerRNA *UNUSED(ptr), PropertyRNA *prop, float *values)
3172 {
3173         FloatPropertyRNA *fprop = (FloatPropertyRNA *)rna_ensure_property(prop);
3174
3175         BLI_assert(RNA_property_type(prop) == PROP_FLOAT);
3176         BLI_assert(RNA_property_array_check(prop) != false);
3177
3178         if (prop->arraydimension == 0)
3179                 values[0] = fprop->defaultvalue;
3180         else
3181                 rna_property_float_get_default_array_values(fprop, values);
3182 }
3183
3184 float RNA_property_float_get_default_index(PointerRNA *ptr, PropertyRNA *prop, int index)
3185 {
3186         float tmp[RNA_MAX_ARRAY_LENGTH];
3187         int len = rna_ensure_property_array_length(ptr, prop);
3188
3189         BLI_assert(RNA_property_type(prop) == PROP_FLOAT);
3190         BLI_assert(RNA_property_array_check(prop) != false);
3191         BLI_assert(index >= 0);
3192         BLI_assert(index < prop->totarraylength);
3193
3194         if (len <= RNA_MAX_ARRAY_LENGTH) {
3195                 RNA_property_float_get_default_array(ptr, prop, tmp);
3196                 return tmp[index];
3197         }
3198         else {
3199                 float *tmparray, value;
3200
3201                 tmparray = MEM_mallocN(sizeof(float) * len, __func__);
3202                 RNA_property_float_get_default_array(ptr, prop, tmparray);
3203                 value = tmparray[index];
3204                 MEM_freeN(tmparray);
3205
3206                 return value;
3207         }
3208 }
3209
3210 void RNA_property_string_get(PointerRNA *ptr, PropertyRNA *prop, char *value)
3211 {
3212         StringPropertyRNA *sprop = (StringPropertyRNA *)prop;
3213         IDProperty *idprop;
3214
3215         BLI_assert(RNA_property_type(prop) == PROP_STRING);
3216
3217         if ((idprop = rna_idproperty_check(&prop, ptr))) {
3218                 /* editing bytes is not 100% supported
3219                  * since they can contain NIL chars */
3220                 if (idprop->subtype == IDP_STRING_SUB_BYTE) {
3221                         memcpy(value, IDP_String(idprop), idprop->len);
3222                         value[idprop->len] = '\0';
3223                 }
3224                 else {
3225                         memcpy(value, IDP_String(idprop), idprop->len);
3226                 }
3227         }
3228         else if (sprop->get) {
3229                 sprop->get(ptr, value);
3230         }
3231         else if (sprop->get_ex) {
3232                 sprop->get_ex(ptr, prop, value);
3233         }
3234         else {
3235                 strcpy(value, sprop->defaultvalue);
3236         }
3237 }
3238
3239 char *RNA_property_string_get_alloc(PointerRNA *ptr, PropertyRNA *prop,
3240                                     char *fixedbuf, int fixedlen, int *r_len)
3241 {
3242         char *buf;
3243         int length;
3244
3245         BLI_assert(RNA_property_type(prop) == PROP_STRING);
3246
3247         length = RNA_property_string_length(ptr, prop);
3248
3249         if (length + 1 < fixedlen)
3250                 buf = fixedbuf;
3251         else
3252                 buf = MEM_mallocN(sizeof(char) * (length + 1), "RNA_string_get_alloc");
3253
3254 #ifndef NDEBUG
3255         /* safety check to ensure the string is actually set */
3256         buf[length] = 255;
3257 #endif
3258
3259         RNA_property_string_get(ptr, prop, buf);
3260
3261 #ifndef NDEBUG
3262         BLI_assert(buf[length] == '\0');
3263 #endif
3264
3265         if (r_len) {
3266                 *r_len = length;
3267         }
3268
3269         return buf;
3270 }
3271
3272 /* this is the length without \0 terminator */
3273 int RNA_property_string_length(PointerRNA *ptr, PropertyRNA *prop)
3274 {
3275         StringPropertyRNA *sprop = (StringPropertyRNA *)prop;
3276         IDProperty *idprop;
3277
3278         BLI_assert(RNA_property_type(prop) == PROP_STRING);
3279
3280         if ((idprop = rna_idproperty_check(&prop, ptr))) {
3281                 if (idprop->subtype == IDP_STRING_SUB_BYTE) {
3282                         return idprop->len;
3283                 }
3284                 else {
3285 #ifndef NDEBUG
3286                         /* these _must_ stay in sync */
3287                         BLI_assert(strlen(IDP_String(idprop)) == idprop->len - 1);
3288 #endif
3289                         return idprop->len - 1;
3290                 }
3291         }
3292         else if (sprop->length)
3293                 return sprop->length(ptr);
3294         else if (sprop->length_ex)
3295                 return sprop->length_ex(ptr, prop);
3296         else
3297                 return strlen(sprop->defaultvalue);
3298 }
3299
3300 void RNA_property_string_set(PointerRNA *ptr, PropertyRNA *prop, const char *value)
3301 {
3302         StringPropertyRNA *sprop = (StringPropertyRNA *)prop;
3303         IDProperty *idprop;
3304
3305         BLI_assert(RNA_property_type(prop) == PROP_STRING);
3306
3307         if ((idprop = rna_idproperty_check(&prop, ptr))) {
3308                 /* both IDP_STRING_SUB_BYTE / IDP_STRING_SUB_UTF8 */
3309                 IDP_AssignString(idprop, value, RNA_property_string_maxlength(prop) - 1);
3310                 rna_idproperty_touch(idprop);
3311         }
3312         else if (sprop->set)
3313                 sprop->set(ptr, value);  /* set function needs to clamp its self */
3314         else if (sprop->set_ex)
3315                 sprop->set_ex(ptr, prop, value);  /* set function needs to clamp its self */
3316         else if (prop->flag & PROP_EDITABLE) {
3317                 IDProperty *group;
3318
3319                 group = RNA_struct_idprops(ptr, 1);
3320                 if (group)
3321                         IDP_AddToGroup(group, IDP_NewString(value, prop->identifier, RNA_property_string_maxlength(prop)));
3322         }
3323 }
3324
3325 void RNA_property_string_set_bytes(PointerRNA *ptr, PropertyRNA *prop, const char *value, int len)
3326 {
3327         StringPropertyRNA *sprop = (StringPropertyRNA *)prop;
3328         IDProperty *idprop;
3329
3330         BLI_assert(RNA_property_type(prop) == PROP_STRING);
3331         BLI_assert(RNA_property_subtype(prop) == PROP_BYTESTRING);
3332
3333         if ((idprop = rna_idproperty_check(&prop, ptr))) {
3334                 IDP_ResizeArray(idprop, len);
3335                 memcpy(idprop->data.pointer, value, (size_t)len);
3336
3337                 rna_idproperty_touch(idprop);
3338         }
3339         else if (sprop->set) {
3340                 /* XXX, should take length argument (currently not used). */
3341                 sprop->set(ptr, value);  /* set function needs to clamp its self */
3342         }
3343         else if (sprop->set_ex) {
3344                 /* XXX, should take length argument (currently not used). */
3345                 sprop->set_ex(ptr, prop, value);  /* set function needs to clamp its self */
3346         }
3347         else if (prop->flag & PROP_EDITABLE) {
3348                 IDProperty *group;
3349
3350                 group = RNA_struct_idprops(ptr, 1);
3351                 if (group) {
3352                         IDPropertyTemplate val = {0};
3353                         val.string.str = value;
3354                         val.string.len = len;
3355                         val.string.subtype = IDP_STRING_SUB_BYTE;
3356                         IDP_AddToGroup(group, IDP_New(IDP_STRING, &val, prop->identifier));
3357                 }
3358         }
3359 }
3360
3361 void RNA_property_string_get_default(PointerRNA *UNUSED(ptr), PropertyRNA *prop, char *value)
3362 {
3363         StringPropertyRNA *sprop = (StringPropertyRNA *)rna_ensure_property(prop);
3364
3365         BLI_assert(RNA_property_type(prop) == PROP_STRING);
3366
3367         strcpy(value, sprop->defaultvalue);
3368 }
3369
3370 char *RNA_property_string_get_default_alloc(PointerRNA *ptr, PropertyRNA *prop, char *fixedbuf, int fixedlen)
3371 {
3372         char *buf;
3373         int length;
3374
3375         BLI_assert(RNA_property_type(prop) == PROP_STRING);
3376
3377         length = RNA_property_string_default_length(ptr, prop);
3378
3379         if (length + 1 < fixedlen)
3380                 buf = fixedbuf;
3381         else
3382                 buf = MEM_callocN(sizeof(char) * (length + 1), "RNA_string_get_alloc");
3383
3384         RNA_property_string_get_default(ptr, prop, buf);
3385
3386         return buf;
3387 }
3388
3389 /* this is the length without \0 terminator */
3390 int RNA_property_string_default_length(PointerRNA *UNUSED(ptr), PropertyRNA *prop)
3391 {
3392         StringPropertyRNA *sprop = (StringPropertyRNA *)prop;
3393
3394         BLI_assert(RNA_property_type(prop) == PROP_STRING);
3395
3396         return strlen(sprop->defaultvalue);
3397 }
3398
3399 int RNA_property_enum_get(PointerRNA *ptr, PropertyRNA *prop)
3400 {
3401         EnumPropertyRNA *eprop = (EnumPropertyRNA *)prop;
3402         IDProperty *idprop;
3403