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