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