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