doxygen: blender/makesrna tagged.
[blender.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= {{0}};
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= {{0}};
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 /* low level direct access to type->properties, note this ignores parent classes so should be used with care */
578 const struct ListBase *RNA_struct_type_properties(StructRNA *srna)
579 {
580         return &srna->cont.properties;
581 }
582
583 PropertyRNA *RNA_struct_type_find_property(StructRNA *srna, const char *identifier)
584 {
585         return BLI_findstring_ptr(&srna->cont.properties, identifier, offsetof(PropertyRNA, identifier));
586 }
587
588 FunctionRNA *RNA_struct_find_function(PointerRNA *ptr, const char *identifier)
589 {
590 #if 1
591         FunctionRNA *func;
592         StructRNA *type;
593         for(type= ptr->type; type; type= type->base) {
594                 func= (FunctionRNA *)BLI_findstring_ptr(&type->functions, identifier, offsetof(FunctionRNA, identifier));
595                 if(func) {
596                         return func;
597                 }
598         }
599         return NULL;
600
601         /* funcitonal but slow */
602 #else
603         PointerRNA tptr;
604         PropertyRNA *iterprop;
605         FunctionRNA *func;
606
607         RNA_pointer_create(NULL, &RNA_Struct, ptr->type, &tptr);
608         iterprop= RNA_struct_find_property(&tptr, "functions");
609
610         func= NULL;
611
612         RNA_PROP_BEGIN(&tptr, funcptr, iterprop) {
613                 if(strcmp(identifier, RNA_function_identifier(funcptr.data)) == 0) {
614                         func= funcptr.data;
615                         break;
616                 }
617         }
618         RNA_PROP_END;
619
620         return func;
621 #endif
622 }
623
624 const struct ListBase *RNA_struct_type_functions(StructRNA *srna)
625 {
626         return &srna->functions;
627 }
628
629 StructRegisterFunc RNA_struct_register(StructRNA *type)
630 {
631         return type->reg;
632 }
633
634 StructUnregisterFunc RNA_struct_unregister(StructRNA *type)
635 {
636         do {
637                 if(type->unreg)
638                         return type->unreg;
639         } while((type=type->base));
640
641         return NULL;
642 }
643
644 void *RNA_struct_py_type_get(StructRNA *srna)
645 {
646         return srna->py_type;
647 }
648
649 void RNA_struct_py_type_set(StructRNA *srna, void *py_type)
650 {
651         srna->py_type= py_type;
652 }
653
654 void *RNA_struct_blender_type_get(StructRNA *srna)
655 {
656         return srna->blender_type;
657 }
658
659 void RNA_struct_blender_type_set(StructRNA *srna, void *blender_type)
660 {
661         srna->blender_type= blender_type;
662 }
663
664 char *RNA_struct_name_get_alloc(PointerRNA *ptr, char *fixedbuf, int fixedlen)
665 {
666         PropertyRNA *nameprop;
667
668         if(ptr->data && (nameprop = RNA_struct_name_property(ptr->type)))
669                 return RNA_property_string_get_alloc(ptr, nameprop, fixedbuf, fixedlen);
670
671         return NULL;
672 }
673
674 /* Property Information */
675
676 const char *RNA_property_identifier(PropertyRNA *prop)
677 {
678         return rna_ensure_property_identifier(prop);
679 }
680
681 const char *RNA_property_description(PropertyRNA *prop)
682 {
683         return rna_ensure_property_description(prop);
684 }
685
686 PropertyType RNA_property_type(PropertyRNA *prop)
687 {
688         return rna_ensure_property(prop)->type;
689 }
690
691 PropertySubType RNA_property_subtype(PropertyRNA *prop)
692 {
693         return rna_ensure_property(prop)->subtype;
694 }
695
696 PropertyUnit RNA_property_unit(PropertyRNA *prop)
697 {
698         return RNA_SUBTYPE_UNIT(rna_ensure_property(prop)->subtype);
699 }
700
701 int RNA_property_flag(PropertyRNA *prop)
702 {
703         return rna_ensure_property(prop)->flag;
704 }
705
706 int RNA_property_array_length(PointerRNA *ptr, PropertyRNA *prop)
707 {
708         return rna_ensure_property_array_length(ptr, prop);
709 }
710
711 int RNA_property_array_check(PointerRNA *ptr, PropertyRNA *prop)
712 {
713         return rna_ensure_property_array_check(ptr, prop);
714 }
715
716 /* used by BPY to make an array from the python object */
717 int RNA_property_array_dimension(PointerRNA *ptr, PropertyRNA *prop, int length[])
718 {
719         PropertyRNA *rprop= rna_ensure_property(prop);
720
721         if(length)
722                         rna_ensure_property_multi_array_length(ptr, prop, length);
723
724         return rprop->arraydimension;
725 }
726
727 /* Return the size of Nth dimension. */
728 int RNA_property_multi_array_length(PointerRNA *ptr, PropertyRNA *prop, int dim)
729 {
730         int len[RNA_MAX_ARRAY_DIMENSION];
731
732         rna_ensure_property_multi_array_length(ptr, prop, len);
733
734         return len[dim];
735 }
736
737 char RNA_property_array_item_char(PropertyRNA *prop, int index)
738 {
739         const char *vectoritem= "XYZW";
740         const char *quatitem= "WXYZ";
741         const char *coloritem= "RGBA";
742         PropertySubType subtype= rna_ensure_property(prop)->subtype;
743
744         /* get string to use for array index */
745         if ((index < 4) && ELEM(subtype, PROP_QUATERNION, PROP_AXISANGLE))
746                 return quatitem[index];
747         else if((index < 4) && ELEM7(subtype, PROP_TRANSLATION, PROP_DIRECTION, PROP_XYZ, PROP_XYZ_LENGTH, PROP_EULER, PROP_VELOCITY, PROP_ACCELERATION))
748                 return vectoritem[index];
749         else if ((index < 4) && ELEM(subtype, PROP_COLOR, PROP_COLOR_GAMMA))
750                 return coloritem[index];
751
752         return '\0';
753 }
754
755 int RNA_property_array_item_index(PropertyRNA *prop, char name)
756 {
757         PropertySubType subtype= rna_ensure_property(prop)->subtype;
758
759         name= toupper(name);
760
761         /* get index based on string name/alias */
762         /* maybe a function to find char index in string would be better than all the switches */
763         if (ELEM(subtype, PROP_QUATERNION, PROP_AXISANGLE)) {
764                 switch (name) {
765                         case 'W':
766                                 return 0;
767                         case 'X':
768                                 return 1;
769                         case 'Y':
770                                 return 2;
771                         case 'Z':
772                                 return 3;
773                 }
774         }
775         else if(ELEM6(subtype, PROP_TRANSLATION, PROP_DIRECTION, PROP_XYZ, PROP_EULER, PROP_VELOCITY, PROP_ACCELERATION)) {
776                 switch (name) {
777                         case 'X':
778                                 return 0;
779                         case 'Y':
780                                 return 1;
781                         case 'Z':
782                                 return 2;
783                         case 'W':
784                                 return 3;
785                 }
786         }
787         else if (ELEM(subtype, PROP_COLOR, PROP_COLOR_GAMMA)) {
788                 switch (name) {
789                         case 'R':
790                                 return 0;
791                         case 'G':
792                                 return 1;
793                         case 'B':
794                                 return 2;
795                         case 'A':
796                                 return 3;
797                 }
798         }
799
800         return -1;
801 }
802
803
804 void RNA_property_int_range(PointerRNA *ptr, PropertyRNA *prop, int *hardmin, int *hardmax)
805 {
806         IntPropertyRNA *iprop= (IntPropertyRNA*)rna_ensure_property(prop);
807
808         if(prop->magic != RNA_MAGIC) {
809                 /* attempt to get the local ID values */
810                 IDProperty *idp_ui= rna_idproperty_ui(prop);
811
812                 if(idp_ui) {
813                         IDProperty *item;
814
815                         item= IDP_GetPropertyTypeFromGroup(idp_ui, "min", IDP_INT);
816                         *hardmin= item ? IDP_Int(item) : INT_MIN;
817
818                         item= IDP_GetPropertyTypeFromGroup(idp_ui, "max", IDP_INT);
819                         *hardmax= item ? IDP_Int(item) : INT_MAX;
820
821                         return;
822                 }
823         }
824
825         if(iprop->range) {
826                 iprop->range(ptr, hardmin, hardmax);
827         }
828         else {
829                 *hardmin= iprop->hardmin;
830                 *hardmax= iprop->hardmax;
831         }
832 }
833
834 void RNA_property_int_ui_range(PointerRNA *ptr, PropertyRNA *prop, int *softmin, int *softmax, int *step)
835 {
836         IntPropertyRNA *iprop= (IntPropertyRNA*)rna_ensure_property(prop);
837         int hardmin, hardmax;
838         
839         if(prop->magic != RNA_MAGIC) {
840                 /* attempt to get the local ID values */
841                 IDProperty *idp_ui= rna_idproperty_ui(prop);
842
843                 if(idp_ui) {
844                         IDProperty *item;
845
846                         item= IDP_GetPropertyTypeFromGroup(idp_ui, "soft_min", IDP_INT);
847                         *softmin= item ? IDP_Int(item) : INT_MIN;
848
849                         item= IDP_GetPropertyTypeFromGroup(idp_ui, "soft_max", IDP_INT);
850                         *softmax= item ? IDP_Int(item) : INT_MAX;
851
852                         item= IDP_GetPropertyTypeFromGroup(idp_ui, "step", IDP_INT);
853                         *step= item ? IDP_Int(item) : 1;
854
855                         return;
856                 }
857         }
858
859         if(iprop->range) {
860                 iprop->range(ptr, &hardmin, &hardmax);
861                 *softmin= MAX2(iprop->softmin, hardmin);
862                 *softmax= MIN2(iprop->softmax, hardmax);
863         }
864         else {
865                 *softmin= iprop->softmin;
866                 *softmax= iprop->softmax;
867         }
868
869         *step= iprop->step;
870 }
871
872 void RNA_property_float_range(PointerRNA *ptr, PropertyRNA *prop, float *hardmin, float *hardmax)
873 {
874         FloatPropertyRNA *fprop= (FloatPropertyRNA*)rna_ensure_property(prop);
875
876         if(prop->magic != RNA_MAGIC) {
877                 /* attempt to get the local ID values */
878                 IDProperty *idp_ui= rna_idproperty_ui(prop);
879
880                 if(idp_ui) {
881                         IDProperty *item;
882
883                         item= IDP_GetPropertyTypeFromGroup(idp_ui, "min", IDP_DOUBLE);
884                         *hardmin= item ? IDP_Double(item) : FLT_MIN; 
885
886                         item= IDP_GetPropertyTypeFromGroup(idp_ui, "max", IDP_DOUBLE);
887                         *hardmax= item ? IDP_Double(item) : FLT_MAX;
888
889                         return;
890                 }
891         }
892
893         if(fprop->range) {
894                 fprop->range(ptr, hardmin, hardmax);
895         }
896         else {
897                 *hardmin= fprop->hardmin;
898                 *hardmax= fprop->hardmax;
899         }
900 }
901
902 void RNA_property_float_ui_range(PointerRNA *ptr, PropertyRNA *prop, float *softmin, float *softmax, float *step, float *precision)
903 {
904         FloatPropertyRNA *fprop= (FloatPropertyRNA*)rna_ensure_property(prop);
905         float hardmin, hardmax;
906
907         if(prop->magic != RNA_MAGIC) {
908                 /* attempt to get the local ID values */
909                 IDProperty *idp_ui= rna_idproperty_ui(prop);
910
911                 if(idp_ui) {
912                         IDProperty *item;
913
914                         item= IDP_GetPropertyTypeFromGroup(idp_ui, "soft_min", IDP_DOUBLE);
915                         *softmin= item ? IDP_Double(item) : FLT_MIN;
916
917                         item= IDP_GetPropertyTypeFromGroup(idp_ui, "soft_max", IDP_DOUBLE);
918                         *softmax= item ? IDP_Double(item) : FLT_MAX;
919
920                         item= IDP_GetPropertyTypeFromGroup(idp_ui, "step", IDP_DOUBLE);
921                         *step= item ? IDP_Double(item) : 1.0f;
922
923                         item= IDP_GetPropertyTypeFromGroup(idp_ui, "precision", IDP_DOUBLE);
924                         *precision= item ? IDP_Double(item) : 3.0f;
925
926                         return;
927                 }
928         }
929
930         if(fprop->range) {
931                 fprop->range(ptr, &hardmin, &hardmax);
932                 *softmin= MAX2(fprop->softmin, hardmin);
933                 *softmax= MIN2(fprop->softmax, hardmax);
934         }
935         else {
936                 *softmin= fprop->softmin;
937                 *softmax= fprop->softmax;
938         }
939
940         *step= fprop->step;
941         *precision= (float)fprop->precision;
942 }
943
944 int RNA_property_float_clamp(PointerRNA *ptr, PropertyRNA *prop, float *value)
945 {
946         float min, max;
947
948         RNA_property_float_range(ptr, prop, &min, &max);
949
950         if(*value < min) {
951                 *value= min;
952                 return -1;
953         }
954         else if(*value > max) {
955                 *value= max;
956                 return 1;
957         }
958         else {
959                 return 0;
960         }
961 }
962
963 int RNA_property_int_clamp(PointerRNA *ptr, PropertyRNA *prop, int *value)
964 {
965         int min, max;
966
967         RNA_property_int_range(ptr, prop, &min, &max);
968
969         if(*value < min) {
970                 *value= min;
971                 return -1;
972         }
973         else if(*value > max) {
974                 *value= max;
975                 return 1;
976         }
977         else {
978                 return 0;
979         }
980 }
981
982 /* this is the max length including \0 terminator.
983  * '0' used when their is no maximum */
984 int RNA_property_string_maxlength(PropertyRNA *prop)
985 {
986         StringPropertyRNA *sprop= (StringPropertyRNA*)rna_ensure_property(prop);
987         return sprop->maxlength;
988 }
989
990 StructRNA *RNA_property_pointer_type(PointerRNA *ptr, PropertyRNA *prop)
991 {
992         prop= rna_ensure_property(prop);
993
994         if(prop->type == PROP_POINTER) {
995                 PointerPropertyRNA *pprop= (PointerPropertyRNA*)prop;
996
997                 if(pprop->typef)
998                         return pprop->typef(ptr);
999                 else if(pprop->type)
1000                         return pprop->type;
1001         }
1002         else if(prop->type == PROP_COLLECTION) {
1003                 CollectionPropertyRNA *cprop= (CollectionPropertyRNA*)prop;
1004
1005                 if(cprop->item_type)
1006                         return cprop->item_type;
1007         }
1008
1009         return &RNA_UnknownType;
1010 }
1011
1012 int RNA_property_pointer_poll(PointerRNA *ptr, PropertyRNA *prop, PointerRNA *value)
1013 {
1014         prop= rna_ensure_property(prop);
1015
1016         if(prop->type == PROP_POINTER) {
1017                 PointerPropertyRNA *pprop= (PointerPropertyRNA*)prop;
1018                 if(pprop->poll)
1019                         return pprop->poll(ptr, *value);
1020
1021                 return 1;
1022         }
1023
1024         printf("RNA_property_pointer_poll %s: is not a pointer property.\n", prop->identifier);
1025         return 0;
1026 }
1027
1028 /* Reuse for dynamic types  */
1029 EnumPropertyItem DummyRNA_NULL_items[] = {
1030         {0, NULL, 0, NULL, NULL}
1031 };
1032
1033 /* Reuse for dynamic types with default value */
1034 EnumPropertyItem DummyRNA_DEFAULT_items[] = {
1035         {0, "DEFAULT", 0, "Default", ""},
1036         {0, NULL, 0, NULL, NULL}
1037 };
1038
1039 void RNA_property_enum_items(bContext *C, PointerRNA *ptr, PropertyRNA *prop, EnumPropertyItem **item, int *totitem, int *free)
1040 {
1041         EnumPropertyRNA *eprop= (EnumPropertyRNA*)rna_ensure_property(prop);
1042
1043         *free= 0;
1044
1045         if(eprop->itemf && (C != NULL || (prop->flag & PROP_ENUM_NO_CONTEXT))) {
1046                 int tot= 0;
1047
1048                 if (prop->flag & PROP_ENUM_NO_CONTEXT)
1049                         *item= eprop->itemf(NULL, ptr, free);
1050                 else
1051                         *item= eprop->itemf(C, ptr, free);
1052
1053                 if(totitem) {
1054                         if(*item) {
1055                                 for( ; (*item)[tot].identifier; tot++);
1056                         }
1057
1058                         *totitem= tot;
1059                 }
1060         }
1061         else {
1062                 *item= eprop->item;
1063                 if(totitem)
1064                         *totitem= eprop->totitem;
1065         }
1066 }
1067
1068 int RNA_property_enum_value(bContext *C, PointerRNA *ptr, PropertyRNA *prop, const char *identifier, int *value)
1069 {       
1070         EnumPropertyItem *item, *item_array;
1071         int free, found;
1072         
1073         RNA_property_enum_items(C, ptr, prop, &item_array, NULL, &free);
1074         
1075         for(item= item_array; item->identifier; item++) {
1076                 if(item->identifier[0] && strcmp(item->identifier, identifier)==0) {
1077                         *value = item->value;
1078                         break;
1079                 }
1080         }
1081         
1082         found= (item->identifier != NULL); /* could be alloc'd, assign before free */
1083
1084         if(free)
1085                 MEM_freeN(item_array);
1086
1087         return found;
1088 }
1089
1090 int RNA_enum_identifier(EnumPropertyItem *item, const int value, const char **identifier)
1091 {
1092         for (; item->identifier; item++) {
1093                 if(item->identifier[0] && item->value==value) {
1094                         *identifier = item->identifier;
1095                         return 1;
1096                 }
1097         }
1098         return 0;
1099 }
1100
1101 int RNA_enum_bitflag_identifiers(EnumPropertyItem *item, const int value, const char **identifier)
1102 {
1103         int index= 0;
1104         for (; item->identifier; item++) {
1105                 if(item->identifier[0] && item->value & value) {
1106                         identifier[index++] = item->identifier;
1107                 }
1108         }
1109         identifier[index]= NULL;
1110         return index;
1111 }
1112
1113 int RNA_enum_name(EnumPropertyItem *item, const int value, const char **name)
1114 {
1115         for (; item->identifier; item++) {
1116                 if(item->identifier[0] && item->value==value) {
1117                         *name = item->name;
1118                         return 1;
1119                 }
1120         }
1121         return 0;
1122 }
1123
1124 int RNA_enum_description(EnumPropertyItem *item, const int value, const char **description)
1125 {
1126         for (; item->identifier; item++) {
1127                 if(item->identifier[0] && item->value==value) {
1128                         *description = item->description;
1129                         return 1;
1130                 }
1131         }
1132         return 0;
1133 }
1134
1135 int RNA_property_enum_identifier(bContext *C, PointerRNA *ptr, PropertyRNA *prop, const int value, const char **identifier)
1136 {       
1137         EnumPropertyItem *item= NULL;
1138         int result, free;
1139         
1140         RNA_property_enum_items(C, ptr, prop, &item, NULL, &free);
1141         if(item) {
1142                 result= RNA_enum_identifier(item, value, identifier);
1143                 if(free)
1144                         MEM_freeN(item);
1145
1146                 return result;
1147         }
1148         return 0;
1149 }
1150
1151 int RNA_property_enum_name(bContext *C, PointerRNA *ptr, PropertyRNA *prop, const int value, const char **name)
1152 {       
1153         EnumPropertyItem *item= NULL;
1154         int result, free;
1155         
1156         RNA_property_enum_items(C, ptr, prop, &item, NULL, &free);
1157         if(item) {
1158                 result= RNA_enum_name(item, value, name);
1159                 if(free)
1160                         MEM_freeN(item);
1161                 
1162                 return result;
1163         }
1164         return 0;
1165 }
1166
1167 int RNA_property_enum_bitflag_identifiers(bContext *C, PointerRNA *ptr, PropertyRNA *prop, const int value, const char **identifier)
1168 {
1169         EnumPropertyItem *item= NULL;
1170         int result, free;
1171
1172         RNA_property_enum_items(C, ptr, prop, &item, NULL, &free);
1173         if(item) {
1174                 result= RNA_enum_bitflag_identifiers(item, value, identifier);
1175                 if(free)
1176                         MEM_freeN(item);
1177
1178                 return result;
1179         }
1180         return 0;
1181 }
1182
1183 const char *RNA_property_ui_name(PropertyRNA *prop)
1184 {
1185         return rna_ensure_property_name(prop);
1186 }
1187
1188 const char *RNA_property_ui_description(PropertyRNA *prop)
1189 {
1190         return rna_ensure_property_description(prop);
1191 }
1192
1193 int RNA_property_ui_icon(PropertyRNA *prop)
1194 {
1195         return rna_ensure_property(prop)->icon;
1196 }
1197
1198 int RNA_property_editable(PointerRNA *ptr, PropertyRNA *prop)
1199 {
1200         ID *id= ptr->id.data;
1201         int flag;
1202
1203         prop= rna_ensure_property(prop);
1204         flag= prop->editable ? prop->editable(ptr) : prop->flag;
1205         return (flag & PROP_EDITABLE) && (!id || !id->lib || (prop->flag & PROP_LIB_EXCEPTION));
1206 }
1207
1208 int RNA_property_editable_flag(PointerRNA *ptr, PropertyRNA *prop)
1209 {
1210         int flag;
1211
1212         prop= rna_ensure_property(prop);
1213         flag= prop->editable ? prop->editable(ptr) : prop->flag;
1214         return (flag & PROP_EDITABLE);
1215 }
1216
1217 /* same as RNA_property_editable(), except this checks individual items in an array */
1218 int RNA_property_editable_index(PointerRNA *ptr, PropertyRNA *prop, int index)
1219 {
1220         ID *id;
1221         int flag;
1222
1223         prop= rna_ensure_property(prop);
1224
1225         flag= prop->flag;
1226         
1227         if(prop->editable)
1228                 flag &= prop->editable(ptr);
1229
1230         if (prop->itemeditable)
1231                 flag &= prop->itemeditable(ptr, index);
1232
1233         id= ptr->id.data;
1234
1235         return (flag & PROP_EDITABLE) && (!id || !id->lib || (prop->flag & PROP_LIB_EXCEPTION));
1236 }
1237
1238 int RNA_property_animateable(PointerRNA *ptr, PropertyRNA *prop)
1239 {
1240         /* check that base ID-block can support animation data */
1241         if (!id_type_can_have_animdata(ptr->id.data))
1242                 return 0;
1243         
1244         prop= rna_ensure_property(prop);
1245
1246         if(!(prop->flag & PROP_ANIMATABLE))
1247                 return 0;
1248
1249         return (prop->flag & PROP_EDITABLE);
1250 }
1251
1252 int RNA_property_animated(PointerRNA *ptr, PropertyRNA *prop)
1253 {
1254         /* would need to ask animation system */
1255
1256         return 0;
1257 }
1258
1259
1260 /* this function is to check if its possible to create a valid path from the ID
1261  * its slow so dont call in a loop */
1262 int RNA_property_path_from_ID_check(PointerRNA *ptr, PropertyRNA *prop)
1263 {
1264         char *path= RNA_path_from_ID_to_property(ptr, prop);
1265         int ret= 0;
1266
1267         if(path) {
1268                 PointerRNA id_ptr;
1269                 PointerRNA r_ptr;
1270                 PropertyRNA *r_prop;
1271
1272                 RNA_id_pointer_create(ptr->id.data, &id_ptr);
1273                 RNA_path_resolve(&id_ptr, path, &r_ptr, &r_prop);
1274                 ret= (prop == r_prop);
1275                 MEM_freeN(path);
1276         }
1277
1278         return ret;
1279 }
1280
1281
1282 static void rna_property_update(bContext *C, Main *bmain, Scene *scene, PointerRNA *ptr, PropertyRNA *prop)
1283 {
1284         int is_rna = (prop->magic == RNA_MAGIC);
1285         prop= rna_ensure_property(prop);
1286
1287         if(is_rna) {
1288                 if(prop->update) {
1289                         /* ideally no context would be needed for update, but there's some
1290                            parts of the code that need it still, so we have this exception */
1291                         if(prop->flag & PROP_CONTEXT_UPDATE) {
1292                                 if(C) ((ContextUpdateFunc)prop->update)(C, ptr);
1293                         }
1294                         else
1295                                 prop->update(bmain, scene, ptr);
1296                 }
1297                 if(prop->noteflag)
1298                         WM_main_add_notifier(prop->noteflag, ptr->id.data);
1299         }
1300         else {
1301                 /* WARNING! This is so property drivers update the display!
1302                  * not especially nice  */
1303                 DAG_id_tag_update(ptr->id.data, OB_RECALC_OB|OB_RECALC_DATA|OB_RECALC_TIME);
1304                 WM_main_add_notifier(NC_WINDOW, NULL);
1305         }
1306
1307 }
1308
1309 /* must keep in sync with 'rna_property_update'
1310  * note, its possible this returns a false positive in the case of PROP_CONTEXT_UPDATE
1311  * but this isnt likely to be a performance problem. */
1312 int RNA_property_update_check(PropertyRNA *prop)
1313 {
1314         return (prop->magic != RNA_MAGIC || prop->update || prop->noteflag);
1315 }
1316
1317 void RNA_property_update(bContext *C, PointerRNA *ptr, PropertyRNA *prop)
1318 {
1319         rna_property_update(C, CTX_data_main(C), CTX_data_scene(C), ptr, prop);
1320 }
1321
1322 void RNA_property_update_main(Main *bmain, Scene *scene, PointerRNA *ptr, PropertyRNA *prop)
1323 {
1324         rna_property_update(NULL, bmain, scene, ptr, prop);
1325 }
1326
1327 /* Property Data */
1328
1329 int RNA_property_boolean_get(PointerRNA *ptr, PropertyRNA *prop)
1330 {
1331         BooleanPropertyRNA *bprop= (BooleanPropertyRNA*)prop;
1332         IDProperty *idprop;
1333
1334         if((idprop=rna_idproperty_check(&prop, ptr)))
1335                 return IDP_Int(idprop);
1336         else if(bprop->get)
1337                 return bprop->get(ptr);
1338         else
1339                 return bprop->defaultvalue;
1340 }
1341
1342 void RNA_property_boolean_set(PointerRNA *ptr, PropertyRNA *prop, int value)
1343 {
1344         BooleanPropertyRNA *bprop= (BooleanPropertyRNA*)prop;
1345         IDProperty *idprop;
1346
1347         /* just incase other values are passed */
1348         if(value) value= 1;
1349
1350         if((idprop=rna_idproperty_check(&prop, ptr)))
1351                 IDP_Int(idprop)= value;
1352         else if(bprop->set)
1353                 bprop->set(ptr, value);
1354         else if(prop->flag & PROP_EDITABLE) {
1355                 IDPropertyTemplate val = {0};
1356                 IDProperty *group;
1357
1358                 val.i= value;
1359
1360                 group= RNA_struct_idprops(ptr, 1);
1361                 if(group)
1362                         IDP_AddToGroup(group, IDP_New(IDP_INT, val, (char*)prop->identifier));
1363         }
1364 }
1365
1366 void RNA_property_boolean_get_array(PointerRNA *ptr, PropertyRNA *prop, int *values)
1367 {
1368         BooleanPropertyRNA *bprop= (BooleanPropertyRNA*)prop;
1369         IDProperty *idprop;
1370
1371         if((idprop=rna_idproperty_check(&prop, ptr))) {
1372                 if(prop->arraydimension == 0)
1373                         values[0]= RNA_property_boolean_get(ptr, prop);
1374                 else
1375                         memcpy(values, IDP_Array(idprop), sizeof(int)*idprop->len);
1376         }
1377         else if(prop->arraydimension == 0)
1378                 values[0]= RNA_property_boolean_get(ptr, prop);
1379         else if(bprop->getarray)
1380                 bprop->getarray(ptr, values);
1381         else if(bprop->defaultarray)
1382                 memcpy(values, bprop->defaultarray, sizeof(int)*prop->totarraylength);
1383         else
1384                 memset(values, 0, sizeof(int)*prop->totarraylength);
1385 }
1386
1387 int RNA_property_boolean_get_index(PointerRNA *ptr, PropertyRNA *prop, int index)
1388 {
1389         int tmp[RNA_MAX_ARRAY_LENGTH];
1390         int len= rna_ensure_property_array_length(ptr, prop);
1391
1392         if(len <= RNA_MAX_ARRAY_LENGTH) {
1393                 RNA_property_boolean_get_array(ptr, prop, tmp);
1394                 return tmp[index];
1395         }
1396         else {
1397                 int *tmparray, value;
1398
1399                 tmparray= MEM_callocN(sizeof(int)*len, "RNA_property_boolean_get_index");
1400                 RNA_property_boolean_get_array(ptr, prop, tmparray);
1401                 value= tmparray[index];
1402                 MEM_freeN(tmparray);
1403
1404                 return value;
1405         }
1406 }
1407
1408 void RNA_property_boolean_set_array(PointerRNA *ptr, PropertyRNA *prop, const int *values)
1409 {
1410         BooleanPropertyRNA *bprop= (BooleanPropertyRNA*)prop;
1411         IDProperty *idprop;
1412
1413         if((idprop=rna_idproperty_check(&prop, ptr))) {
1414                 if(prop->arraydimension == 0)
1415                         IDP_Int(idprop)= values[0];
1416                 else
1417                         memcpy(IDP_Array(idprop), values, sizeof(int)*idprop->len);
1418         }
1419         else if(prop->arraydimension == 0)
1420                 RNA_property_boolean_set(ptr, prop, values[0]);
1421         else if(bprop->setarray)
1422                 bprop->setarray(ptr, values);
1423         else if(prop->flag & PROP_EDITABLE) {
1424                 IDPropertyTemplate val = {0};
1425                 IDProperty *group;
1426
1427                 val.array.len= prop->totarraylength;
1428                 val.array.type= IDP_INT;
1429
1430                 group= RNA_struct_idprops(ptr, 1);
1431                 if(group) {
1432                         idprop= IDP_New(IDP_ARRAY, val, (char*)prop->identifier);
1433                         IDP_AddToGroup(group, idprop);
1434                         memcpy(IDP_Array(idprop), values, sizeof(int)*idprop->len);
1435                 }
1436         }
1437 }
1438
1439 void RNA_property_boolean_set_index(PointerRNA *ptr, PropertyRNA *prop, int index, int value)
1440 {
1441         int tmp[RNA_MAX_ARRAY_LENGTH];
1442         int len= rna_ensure_property_array_length(ptr, prop);
1443
1444         if(len <= RNA_MAX_ARRAY_LENGTH) {
1445                 RNA_property_boolean_get_array(ptr, prop, tmp);
1446                 tmp[index]= value;
1447                 RNA_property_boolean_set_array(ptr, prop, tmp);
1448         }
1449         else {
1450                 int *tmparray;
1451
1452                 tmparray= MEM_callocN(sizeof(int)*len, "RNA_property_boolean_get_index");
1453                 RNA_property_boolean_get_array(ptr, prop, tmparray);
1454                 tmparray[index]= value;
1455                 RNA_property_boolean_set_array(ptr, prop, tmparray);
1456                 MEM_freeN(tmparray);
1457         }
1458 }
1459
1460 int RNA_property_boolean_get_default(PointerRNA *ptr, PropertyRNA *prop)
1461 {
1462         BooleanPropertyRNA *bprop= (BooleanPropertyRNA*)prop;
1463         return bprop->defaultvalue;
1464 }
1465
1466 void RNA_property_boolean_get_default_array(PointerRNA *ptr, PropertyRNA *prop, int *values)
1467 {
1468         BooleanPropertyRNA *bprop= (BooleanPropertyRNA*)prop;
1469         
1470         if(prop->arraydimension == 0)
1471                 values[0]= bprop->defaultvalue;
1472         else if(bprop->defaultarray)
1473                 memcpy(values, bprop->defaultarray, sizeof(int)*prop->totarraylength);
1474         else
1475                 memset(values, 0, sizeof(int)*prop->totarraylength);
1476 }
1477
1478 int RNA_property_boolean_get_default_index(PointerRNA *ptr, PropertyRNA *prop, int index)
1479 {
1480         int tmp[RNA_MAX_ARRAY_LENGTH];
1481         int len= rna_ensure_property_array_length(ptr, prop);
1482
1483         if(len <= RNA_MAX_ARRAY_LENGTH) {
1484                 RNA_property_boolean_get_default_array(ptr, prop, tmp);
1485                 return tmp[index];
1486         }
1487         else {
1488                 int *tmparray, value;
1489
1490                 tmparray= MEM_callocN(sizeof(int)*len, "RNA_property_boolean_get_default_index");
1491                 RNA_property_boolean_get_default_array(ptr, prop, tmparray);
1492                 value= tmparray[index];
1493                 MEM_freeN(tmparray);
1494
1495                 return value;
1496         }
1497 }
1498
1499 int RNA_property_int_get(PointerRNA *ptr, PropertyRNA *prop)
1500 {
1501         IntPropertyRNA *iprop= (IntPropertyRNA*)prop;
1502         IDProperty *idprop;
1503
1504         if((idprop=rna_idproperty_check(&prop, ptr)))
1505                 return IDP_Int(idprop);
1506         else if(iprop->get)
1507                 return iprop->get(ptr);
1508         else
1509                 return iprop->defaultvalue;
1510 }
1511
1512 void RNA_property_int_set(PointerRNA *ptr, PropertyRNA *prop, int value)
1513 {
1514         IntPropertyRNA *iprop= (IntPropertyRNA*)prop;
1515         IDProperty *idprop;
1516
1517         if((idprop=rna_idproperty_check(&prop, ptr)))
1518                 IDP_Int(idprop)= value;
1519         else if(iprop->set)
1520                 iprop->set(ptr, value);
1521         else if(prop->flag & PROP_EDITABLE) {
1522                 IDPropertyTemplate val = {0};
1523                 IDProperty *group;
1524
1525                 val.i= value;
1526
1527                 group= RNA_struct_idprops(ptr, 1);
1528                 if(group)
1529                         IDP_AddToGroup(group, IDP_New(IDP_INT, val, (char*)prop->identifier));
1530         }
1531 }
1532
1533 void RNA_property_int_get_array(PointerRNA *ptr, PropertyRNA *prop, int *values)
1534 {
1535         IntPropertyRNA *iprop= (IntPropertyRNA*)prop;
1536         IDProperty *idprop;
1537
1538         if((idprop=rna_idproperty_check(&prop, ptr))) {
1539                 if(prop->arraydimension == 0)
1540                         values[0]= RNA_property_int_get(ptr, prop);
1541                 else
1542                         memcpy(values, IDP_Array(idprop), sizeof(int)*idprop->len);
1543         }
1544         else if(prop->arraydimension == 0)
1545                 values[0]= RNA_property_int_get(ptr, prop);
1546         else if(iprop->getarray)
1547                 iprop->getarray(ptr, values);
1548         else if(iprop->defaultarray)
1549                 memcpy(values, iprop->defaultarray, sizeof(int)*prop->totarraylength);
1550         else
1551                 memset(values, 0, sizeof(int)*prop->totarraylength);
1552 }
1553
1554 int RNA_property_int_get_index(PointerRNA *ptr, PropertyRNA *prop, int index)
1555 {
1556         int tmp[RNA_MAX_ARRAY_LENGTH];
1557         int len= rna_ensure_property_array_length(ptr, prop);
1558
1559         if(len <= RNA_MAX_ARRAY_LENGTH) {
1560                 RNA_property_int_get_array(ptr, prop, tmp);
1561                 return tmp[index];
1562         }
1563         else {
1564                 int *tmparray, value;
1565
1566                 tmparray= MEM_callocN(sizeof(int)*len, "RNA_property_int_get_index");
1567                 RNA_property_int_get_array(ptr, prop, tmparray);
1568                 value= tmparray[index];
1569                 MEM_freeN(tmparray);
1570
1571                 return value;
1572         }
1573 }
1574
1575 void RNA_property_int_set_array(PointerRNA *ptr, PropertyRNA *prop, const int *values)
1576 {
1577         IntPropertyRNA *iprop= (IntPropertyRNA*)prop;
1578         IDProperty *idprop;
1579
1580         if((idprop=rna_idproperty_check(&prop, ptr))) {
1581                 if(prop->arraydimension == 0)
1582                         IDP_Int(idprop)= values[0];
1583                 else
1584                         memcpy(IDP_Array(idprop), values, sizeof(int)*idprop->len);\
1585         }
1586         else if(prop->arraydimension == 0)
1587                 RNA_property_int_set(ptr, prop, values[0]);
1588         else if(iprop->setarray)
1589                 iprop->setarray(ptr, values);
1590         else if(prop->flag & PROP_EDITABLE) {
1591                 IDPropertyTemplate val = {0};
1592                 IDProperty *group;
1593
1594                 val.array.len= prop->totarraylength;
1595                 val.array.type= IDP_INT;
1596
1597                 group= RNA_struct_idprops(ptr, 1);
1598                 if(group) {
1599                         idprop= IDP_New(IDP_ARRAY, val, (char*)prop->identifier);
1600                         IDP_AddToGroup(group, idprop);
1601                         memcpy(IDP_Array(idprop), values, sizeof(int)*idprop->len);
1602                 }
1603         }
1604 }
1605
1606 void RNA_property_int_set_index(PointerRNA *ptr, PropertyRNA *prop, int index, int value)
1607 {
1608         int tmp[RNA_MAX_ARRAY_LENGTH];
1609         int len= rna_ensure_property_array_length(ptr, prop);
1610
1611         if(len <= RNA_MAX_ARRAY_LENGTH) {
1612                 RNA_property_int_get_array(ptr, prop, tmp);
1613                 tmp[index]= value;
1614                 RNA_property_int_set_array(ptr, prop, tmp);
1615         }
1616         else {
1617                 int *tmparray;
1618
1619                 tmparray= MEM_callocN(sizeof(int)*len, "RNA_property_int_get_index");
1620                 RNA_property_int_get_array(ptr, prop, tmparray);
1621                 tmparray[index]= value;
1622                 RNA_property_int_set_array(ptr, prop, tmparray);
1623                 MEM_freeN(tmparray);
1624         }
1625 }
1626
1627 int RNA_property_int_get_default(PointerRNA *ptr, PropertyRNA *prop)
1628 {
1629         IntPropertyRNA *iprop= (IntPropertyRNA*)prop;
1630         return iprop->defaultvalue;
1631 }
1632
1633 void RNA_property_int_get_default_array(PointerRNA *ptr, PropertyRNA *prop, int *values)
1634 {
1635         IntPropertyRNA *iprop= (IntPropertyRNA*)prop;
1636         
1637         if(prop->arraydimension == 0)
1638                 values[0]= iprop->defaultvalue;
1639         else if(iprop->defaultarray)
1640                 memcpy(values, iprop->defaultarray, sizeof(int)*prop->totarraylength);
1641         else
1642                 memset(values, 0, sizeof(int)*prop->totarraylength);
1643 }
1644
1645 int RNA_property_int_get_default_index(PointerRNA *ptr, PropertyRNA *prop, int index)
1646 {
1647         int tmp[RNA_MAX_ARRAY_LENGTH];
1648         int len= rna_ensure_property_array_length(ptr, prop);
1649
1650         if(len <= RNA_MAX_ARRAY_LENGTH) {
1651                 RNA_property_int_get_default_array(ptr, prop, tmp);
1652                 return tmp[index];
1653         }
1654         else {
1655                 int *tmparray, value;
1656
1657                 tmparray= MEM_callocN(sizeof(int)*len, "RNA_property_int_get_default_index");
1658                 RNA_property_int_get_default_array(ptr, prop, tmparray);
1659                 value= tmparray[index];
1660                 MEM_freeN(tmparray);
1661
1662                 return value;
1663         }
1664 }
1665
1666 float RNA_property_float_get(PointerRNA *ptr, PropertyRNA *prop)
1667 {
1668         FloatPropertyRNA *fprop= (FloatPropertyRNA*)prop;
1669         IDProperty *idprop;
1670
1671         if((idprop=rna_idproperty_check(&prop, ptr))) {
1672                 if(idprop->type == IDP_FLOAT)
1673                         return IDP_Float(idprop);
1674                 else
1675                         return (float)IDP_Double(idprop);
1676         }
1677         else if(fprop->get)
1678                 return fprop->get(ptr);
1679         else
1680                 return fprop->defaultvalue;
1681 }
1682
1683 void RNA_property_float_set(PointerRNA *ptr, PropertyRNA *prop, float value)
1684 {
1685         FloatPropertyRNA *fprop= (FloatPropertyRNA*)prop;
1686         IDProperty *idprop;
1687
1688         if((idprop=rna_idproperty_check(&prop, ptr))) {
1689                 if(idprop->type == IDP_FLOAT)
1690                         IDP_Float(idprop)= value;
1691                 else
1692                         IDP_Double(idprop)= value;
1693         }
1694         else if(fprop->set) {
1695                 fprop->set(ptr, value);
1696         }
1697         else if(prop->flag & PROP_EDITABLE) {
1698                 IDPropertyTemplate val = {0};
1699                 IDProperty *group;
1700
1701                 val.f= value;
1702
1703                 group= RNA_struct_idprops(ptr, 1);
1704                 if(group)
1705                         IDP_AddToGroup(group, IDP_New(IDP_FLOAT, val, (char*)prop->identifier));
1706         }
1707 }
1708
1709 void RNA_property_float_get_array(PointerRNA *ptr, PropertyRNA *prop, float *values)
1710 {
1711         FloatPropertyRNA *fprop= (FloatPropertyRNA*)prop;
1712         IDProperty *idprop;
1713         int i;
1714
1715         if((idprop=rna_idproperty_check(&prop, ptr))) {
1716                 if(prop->arraydimension == 0)
1717                         values[0]= RNA_property_float_get(ptr, prop);
1718                 else if(idprop->subtype == IDP_FLOAT) {
1719                         memcpy(values, IDP_Array(idprop), sizeof(float)*idprop->len);
1720                 }
1721                 else {
1722                         for(i=0; i<idprop->len; i++)
1723                                 values[i]=  (float)(((double*)IDP_Array(idprop))[i]);
1724                 }
1725         }
1726         else if(prop->arraydimension == 0)
1727                 values[0]= RNA_property_float_get(ptr, prop);
1728         else if(fprop->getarray)
1729                 fprop->getarray(ptr, values);
1730         else if(fprop->defaultarray)
1731                 memcpy(values, fprop->defaultarray, sizeof(float)*prop->totarraylength);
1732         else
1733                 memset(values, 0, sizeof(float)*prop->totarraylength);
1734 }
1735
1736 float RNA_property_float_get_index(PointerRNA *ptr, PropertyRNA *prop, int index)
1737 {
1738         float tmp[RNA_MAX_ARRAY_LENGTH];
1739         int len= rna_ensure_property_array_length(ptr, prop);
1740
1741         if(len <= RNA_MAX_ARRAY_LENGTH) {
1742                 RNA_property_float_get_array(ptr, prop, tmp);
1743                 return tmp[index];
1744         }
1745         else {
1746                 float *tmparray, value;
1747
1748                 tmparray= MEM_callocN(sizeof(float)*len, "RNA_property_float_get_index");
1749                 RNA_property_float_get_array(ptr, prop, tmparray);
1750                 value= tmparray[index];
1751                 MEM_freeN(tmparray);
1752
1753                 return value;
1754         }
1755
1756 }
1757
1758 void RNA_property_float_set_array(PointerRNA *ptr, PropertyRNA *prop, const float *values)
1759 {
1760         FloatPropertyRNA *fprop= (FloatPropertyRNA*)prop;
1761         IDProperty *idprop;
1762         int i;
1763
1764         if((idprop=rna_idproperty_check(&prop, ptr))) {
1765                 if(prop->arraydimension == 0) {
1766                         if(idprop->type == IDP_FLOAT)
1767                                 IDP_Float(idprop)= values[0];
1768                         else
1769                                 IDP_Double(idprop)= values[0];
1770                 }
1771                 else if(idprop->subtype == IDP_FLOAT) {
1772                         memcpy(IDP_Array(idprop), values, sizeof(float)*idprop->len);
1773                 }
1774                 else {
1775                         for(i=0; i<idprop->len; i++)
1776                                 ((double*)IDP_Array(idprop))[i]= values[i];
1777                 }
1778         }
1779         else if(prop->arraydimension == 0)
1780                 RNA_property_float_set(ptr, prop, values[0]);
1781         else if(fprop->setarray) {
1782                 fprop->setarray(ptr, values);
1783         }
1784         else if(prop->flag & PROP_EDITABLE) {
1785                 IDPropertyTemplate val = {0};
1786                 IDProperty *group;
1787
1788                 val.array.len= prop->totarraylength;
1789                 val.array.type= IDP_FLOAT;
1790
1791                 group= RNA_struct_idprops(ptr, 1);
1792                 if(group) {
1793                         idprop= IDP_New(IDP_ARRAY, val, (char*)prop->identifier);
1794                         IDP_AddToGroup(group, idprop);
1795                         memcpy(IDP_Array(idprop), values, sizeof(float)*idprop->len);
1796                 }
1797         }
1798 }
1799
1800 void RNA_property_float_set_index(PointerRNA *ptr, PropertyRNA *prop, int index, float value)
1801 {
1802         float tmp[RNA_MAX_ARRAY_LENGTH];
1803         int len= rna_ensure_property_array_length(ptr, prop);
1804
1805         if(len <= RNA_MAX_ARRAY_LENGTH) {
1806                 RNA_property_float_get_array(ptr, prop, tmp);
1807                 tmp[index]= value;
1808                 RNA_property_float_set_array(ptr, prop, tmp);
1809         }
1810         else {
1811                 float *tmparray;
1812
1813                 tmparray= MEM_callocN(sizeof(float)*len, "RNA_property_float_get_index");
1814                 RNA_property_float_get_array(ptr, prop, tmparray);
1815                 tmparray[index]= value;
1816                 RNA_property_float_set_array(ptr, prop, tmparray);
1817                 MEM_freeN(tmparray);
1818         }
1819 }
1820
1821 float RNA_property_float_get_default(PointerRNA *ptr, PropertyRNA *prop)
1822 {
1823         FloatPropertyRNA *fprop= (FloatPropertyRNA*)prop;
1824         return fprop->defaultvalue;
1825 }
1826
1827 void RNA_property_float_get_default_array(PointerRNA *ptr, PropertyRNA *prop, float *values)
1828 {
1829         FloatPropertyRNA *fprop= (FloatPropertyRNA*)prop;
1830         
1831         if(prop->arraydimension == 0)
1832                 values[0]= fprop->defaultvalue;
1833         else if(fprop->defaultarray)
1834                 memcpy(values, fprop->defaultarray, sizeof(float)*prop->totarraylength);
1835         else
1836                 memset(values, 0, sizeof(float)*prop->totarraylength);
1837 }
1838
1839 float RNA_property_float_get_default_index(PointerRNA *ptr, PropertyRNA *prop, int index)
1840 {
1841         float tmp[RNA_MAX_ARRAY_LENGTH];
1842         int len= rna_ensure_property_array_length(ptr, prop);
1843
1844         if(len <= RNA_MAX_ARRAY_LENGTH) {
1845                 RNA_property_float_get_default_array(ptr, prop, tmp);
1846                 return tmp[index];
1847         }
1848         else {
1849                 float *tmparray, value;
1850
1851                 tmparray= MEM_callocN(sizeof(float)*len, "RNA_property_float_get_default_index");
1852                 RNA_property_float_get_default_array(ptr, prop, tmparray);
1853                 value= tmparray[index];
1854                 MEM_freeN(tmparray);
1855
1856                 return value;
1857         }
1858 }
1859
1860 void RNA_property_string_get(PointerRNA *ptr, PropertyRNA *prop, char *value)
1861 {
1862         StringPropertyRNA *sprop= (StringPropertyRNA*)prop;
1863         IDProperty *idprop;
1864
1865         if((idprop=rna_idproperty_check(&prop, ptr)))
1866                 strcpy(value, IDP_String(idprop));
1867         else if(sprop->get)
1868                 sprop->get(ptr, value);
1869         else
1870                 strcpy(value, sprop->defaultvalue);
1871 }
1872
1873 char *RNA_property_string_get_alloc(PointerRNA *ptr, PropertyRNA *prop, char *fixedbuf, int fixedlen)
1874 {
1875         char *buf;
1876         int length;
1877
1878         length= RNA_property_string_length(ptr, prop);
1879
1880         if(length+1 < fixedlen)
1881                 buf= fixedbuf;
1882         else
1883                 buf= MEM_callocN(sizeof(char)*(length+1), "RNA_string_get_alloc");
1884
1885         RNA_property_string_get(ptr, prop, buf);
1886
1887         return buf;
1888 }
1889
1890 /* this is the length without \0 terminator */
1891 int RNA_property_string_length(PointerRNA *ptr, PropertyRNA *prop)
1892 {
1893         StringPropertyRNA *sprop= (StringPropertyRNA*)prop;
1894         IDProperty *idprop;
1895
1896         if((idprop=rna_idproperty_check(&prop, ptr)))
1897                 return strlen(IDP_String(idprop));
1898         else if(sprop->length)
1899                 return sprop->length(ptr);
1900         else
1901                 return strlen(sprop->defaultvalue);
1902 }
1903
1904 void RNA_property_string_set(PointerRNA *ptr, PropertyRNA *prop, const char *value)
1905 {
1906         StringPropertyRNA *sprop= (StringPropertyRNA*)prop;
1907         IDProperty *idprop;
1908
1909         if((idprop=rna_idproperty_check(&prop, ptr)))
1910                 IDP_AssignString(idprop, (char*)value, RNA_property_string_maxlength(prop) - 1);
1911         else if(sprop->set)
1912                 sprop->set(ptr, value); /* set function needs to clamp its self */
1913         else if(prop->flag & PROP_EDITABLE) {
1914                 IDProperty *group;
1915
1916                 group= RNA_struct_idprops(ptr, 1);
1917                 if(group)
1918                         IDP_AddToGroup(group, IDP_NewString((char*)value, (char*)prop->identifier, RNA_property_string_maxlength(prop) - 1));
1919         }
1920 }
1921
1922 void RNA_property_string_get_default(PointerRNA *ptr, PropertyRNA *prop, char *value)
1923 {
1924         StringPropertyRNA *sprop= (StringPropertyRNA*)prop;
1925         strcpy(value, sprop->defaultvalue);
1926 }
1927
1928 char *RNA_property_string_get_default_alloc(PointerRNA *ptr, PropertyRNA *prop, char *fixedbuf, int fixedlen)
1929 {
1930         char *buf;
1931         int length;
1932
1933         length= RNA_property_string_default_length(ptr, prop);
1934
1935         if(length+1 < fixedlen)
1936                 buf= fixedbuf;
1937         else
1938                 buf= MEM_callocN(sizeof(char)*(length+1), "RNA_string_get_alloc");
1939
1940         RNA_property_string_get_default(ptr, prop, buf);
1941
1942         return buf;
1943 }
1944
1945 /* this is the length without \0 terminator */
1946 int RNA_property_string_default_length(PointerRNA *ptr, PropertyRNA *prop)
1947 {
1948         StringPropertyRNA *sprop= (StringPropertyRNA*)prop;
1949         return strlen(sprop->defaultvalue);
1950 }
1951
1952 int RNA_property_enum_get(PointerRNA *ptr, PropertyRNA *prop)
1953 {
1954         EnumPropertyRNA *eprop= (EnumPropertyRNA*)prop;
1955         IDProperty *idprop;
1956
1957         if((idprop=rna_idproperty_check(&prop, ptr)))
1958                 return IDP_Int(idprop);
1959         else if(eprop->get)
1960                 return eprop->get(ptr);
1961         else
1962                 return eprop->defaultvalue;
1963 }
1964
1965 void RNA_property_enum_set(PointerRNA *ptr, PropertyRNA *prop, int value)
1966 {
1967         EnumPropertyRNA *eprop= (EnumPropertyRNA*)prop;
1968         IDProperty *idprop;
1969
1970         if((idprop=rna_idproperty_check(&prop, ptr)))
1971                 IDP_Int(idprop)= value;
1972         else if(eprop->set) {
1973                 eprop->set(ptr, value);
1974         }
1975         else if(prop->flag & PROP_EDITABLE) {
1976                 IDPropertyTemplate val = {0};
1977                 IDProperty *group;
1978
1979                 val.i= value;
1980
1981                 group= RNA_struct_idprops(ptr, 1);
1982                 if(group)
1983                         IDP_AddToGroup(group, IDP_New(IDP_INT, val, (char*)prop->identifier));
1984         }
1985 }
1986
1987 int RNA_property_enum_get_default(PointerRNA *ptr, PropertyRNA *prop)
1988 {
1989         EnumPropertyRNA *eprop= (EnumPropertyRNA*)prop;
1990         return eprop->defaultvalue;
1991 }
1992
1993
1994 PointerRNA RNA_property_pointer_get(PointerRNA *ptr, PropertyRNA *prop)
1995 {
1996         PointerPropertyRNA *pprop= (PointerPropertyRNA*)prop;
1997         IDProperty *idprop;
1998
1999         if((idprop=rna_idproperty_check(&prop, ptr))) {
2000                 pprop= (PointerPropertyRNA*)prop;
2001
2002                 /* for groups, data is idprop itself */
2003                 return rna_pointer_inherit_refine(ptr, pprop->type, idprop);
2004         }
2005         else if(pprop->get) {
2006                 return pprop->get(ptr);
2007         }
2008         else if(prop->flag & PROP_IDPROPERTY) {
2009                 /* XXX temporary hack to add it automatically, reading should
2010                    never do any write ops, to ensure thread safety etc .. */
2011                 RNA_property_pointer_add(ptr, prop);
2012                 return RNA_property_pointer_get(ptr, prop);
2013         }
2014         else {
2015                 return PointerRNA_NULL;
2016         }
2017 }
2018
2019 void RNA_property_pointer_set(PointerRNA *ptr, PropertyRNA *prop, PointerRNA ptr_value)
2020 {
2021         /*IDProperty *idprop;*/
2022
2023         if((/*idprop=*/ rna_idproperty_check(&prop, ptr))) {
2024                 /* not supported */
2025         }
2026         else {
2027                 PointerPropertyRNA *pprop= (PointerPropertyRNA*)prop;
2028
2029                 if(             pprop->set &&
2030                                 !((prop->flag & PROP_NEVER_NULL) && ptr_value.data == NULL) &&
2031                                 !((prop->flag & PROP_ID_SELF_CHECK) && ptr->id.data == ptr_value.id.data)
2032                 ) {
2033                         pprop->set(ptr, ptr_value);
2034                 }
2035         }
2036 }
2037
2038 PointerRNA RNA_property_pointer_get_default(PointerRNA *UNUSED(ptr), PropertyRNA *UNUSED(prop))
2039 {
2040         //PointerPropertyRNA *pprop= (PointerPropertyRNA*)prop;
2041         return PointerRNA_NULL; // FIXME: there has to be a way...
2042 }
2043
2044 void RNA_property_pointer_add(PointerRNA *ptr, PropertyRNA *prop)
2045 {
2046         /*IDProperty *idprop;*/
2047
2048         if((/*idprop=*/rna_idproperty_check(&prop, ptr))) {
2049                 /* already exists */
2050         }
2051         else if(prop->flag & PROP_IDPROPERTY) {
2052                 IDPropertyTemplate val = {0};
2053                 IDProperty *group;
2054
2055                 val.i= 0;
2056
2057                 group= RNA_struct_idprops(ptr, 1);
2058                 if(group)
2059                         IDP_AddToGroup(group, IDP_New(IDP_GROUP, val, (char*)prop->identifier));
2060         }
2061         else
2062                 printf("RNA_property_pointer_add %s.%s: only supported for id properties.\n", ptr->type->identifier, prop->identifier);
2063 }
2064
2065 void RNA_property_pointer_remove(PointerRNA *ptr, PropertyRNA *prop)
2066 {
2067         IDProperty *idprop, *group;
2068
2069         if((idprop=rna_idproperty_check(&prop, ptr))) {
2070                 group= RNA_struct_idprops(ptr, 0);
2071                 
2072                 if(group) {
2073                         IDP_RemFromGroup(group, idprop);
2074                         IDP_FreeProperty(idprop);
2075                         MEM_freeN(idprop);
2076                 }
2077         }
2078         else
2079                 printf("RNA_property_pointer_remove %s.%s: only supported for id properties.\n", ptr->type->identifier, prop->identifier);
2080 }
2081
2082 static void rna_property_collection_get_idp(CollectionPropertyIterator *iter)
2083 {
2084         CollectionPropertyRNA *cprop= (CollectionPropertyRNA*)iter->prop;
2085
2086         iter->ptr.data= rna_iterator_array_get(iter);
2087         iter->ptr.type= cprop->item_type;
2088         rna_pointer_inherit_id(cprop->item_type, &iter->parent, &iter->ptr);
2089 }
2090
2091 void RNA_property_collection_begin(PointerRNA *ptr, PropertyRNA *prop, CollectionPropertyIterator *iter)
2092 {
2093         IDProperty *idprop;
2094
2095         memset(iter, 0, sizeof(*iter));
2096
2097         if((idprop=rna_idproperty_check(&prop, ptr)) || (prop->flag & PROP_IDPROPERTY)) {
2098                 iter->parent= *ptr;
2099                 iter->prop= prop;
2100
2101                 if(idprop)
2102                         rna_iterator_array_begin(iter, IDP_IDPArray(idprop), sizeof(IDProperty), idprop->len, 0, NULL);
2103                 else
2104                         rna_iterator_array_begin(iter, NULL, sizeof(IDProperty), 0, 0, NULL);
2105
2106                 if(iter->valid)
2107                         rna_property_collection_get_idp(iter);
2108
2109                 iter->idprop= 1;
2110         }
2111         else {
2112                 CollectionPropertyRNA *cprop= (CollectionPropertyRNA*)prop;
2113                 cprop->begin(iter, ptr);
2114         }
2115 }
2116
2117 void RNA_property_collection_next(CollectionPropertyIterator *iter)
2118 {
2119         CollectionPropertyRNA *cprop= (CollectionPropertyRNA*)rna_ensure_property(iter->prop);
2120
2121         if(iter->idprop) {
2122                 rna_iterator_array_next(iter);
2123
2124                 if(iter->valid)
2125                         rna_property_collection_get_idp(iter);
2126         }
2127         else
2128                 cprop->next(iter);
2129 }
2130
2131 void RNA_property_collection_end(CollectionPropertyIterator *iter)
2132 {
2133         CollectionPropertyRNA *cprop= (CollectionPropertyRNA*)rna_ensure_property(iter->prop);
2134
2135         if(iter->idprop)
2136                 rna_iterator_array_end(iter);
2137         else
2138                 cprop->end(iter);
2139 }
2140
2141 int RNA_property_collection_length(PointerRNA *ptr, PropertyRNA *prop)
2142 {
2143         CollectionPropertyRNA *cprop= (CollectionPropertyRNA*)prop;
2144         IDProperty *idprop;
2145
2146         if((idprop=rna_idproperty_check(&prop, ptr))) {
2147                 return idprop->len;
2148         }
2149         else if(cprop->length) {
2150                 return cprop->length(ptr);
2151         }
2152         else {
2153                 CollectionPropertyIterator iter;
2154                 int length= 0;
2155
2156                 RNA_property_collection_begin(ptr, prop, &iter);
2157                 for(; iter.valid; RNA_property_collection_next(&iter))
2158                         length++;
2159                 RNA_property_collection_end(&iter);
2160
2161                 return length;
2162         }
2163 }
2164
2165 void RNA_property_collection_add(PointerRNA *ptr, PropertyRNA *prop, PointerRNA *r_ptr)
2166 {
2167         IDProperty *idprop;
2168 //      CollectionPropertyRNA *cprop= (CollectionPropertyRNA*)prop;
2169
2170         if((idprop=rna_idproperty_check(&prop, ptr))) {
2171                 IDPropertyTemplate val = {0};
2172                 IDProperty *item;
2173
2174                 item= IDP_New(IDP_GROUP, val, "");
2175                 IDP_AppendArray(idprop, item);
2176                 // IDP_FreeProperty(item); // IDP_AppendArray does a shallow copy (memcpy), only free memory 
2177                 MEM_freeN(item);
2178         }
2179         else if(prop->flag & PROP_IDPROPERTY) {
2180                 IDProperty *group, *item;
2181                 IDPropertyTemplate val = {0};
2182
2183                 group= RNA_struct_idprops(ptr, 1);
2184                 if(group) {
2185                         idprop= IDP_NewIDPArray(prop->identifier);
2186                         IDP_AddToGroup(group, idprop);
2187
2188                         item= IDP_New(IDP_GROUP, val, "");
2189                         IDP_AppendArray(idprop, item);
2190                         // IDP_FreeProperty(item); // IDP_AppendArray does a shallow copy (memcpy), only free memory
2191                         MEM_freeN(item);
2192                 }
2193         }
2194
2195         /* py api calls directly */
2196 #if 0
2197         else if(cprop->add){
2198                 if(!(cprop->add->flag & FUNC_USE_CONTEXT)) { /* XXX check for this somewhere else */
2199                         ParameterList params;
2200                         RNA_parameter_list_create(&params, ptr, cprop->add);
2201                         RNA_function_call(NULL, NULL, ptr, cprop->add, &params);
2202                         RNA_parameter_list_free(&params);
2203                 }
2204         }
2205         /*else
2206                 printf("RNA_property_collection_add %s.%s: not implemented for this property.\n", ptr->type->identifier, prop->identifier);*/
2207 #endif
2208
2209         if(r_ptr) {
2210                 if(idprop) {
2211                         CollectionPropertyRNA *cprop= (CollectionPropertyRNA*)prop;
2212
2213                         r_ptr->data= IDP_GetIndexArray(idprop, idprop->len-1);
2214                         r_ptr->type= cprop->item_type;
2215                         rna_pointer_inherit_id(NULL, ptr, r_ptr);
2216                 }
2217                 else
2218                         memset(r_ptr, 0, sizeof(*r_ptr));
2219         }
2220 }
2221
2222 int RNA_property_collection_remove(PointerRNA *ptr, PropertyRNA *prop, int key)
2223 {
2224         IDProperty *idprop;
2225 //      CollectionPropertyRNA *cprop= (CollectionPropertyRNA*)prop;
2226
2227         if((idprop=rna_idproperty_check(&prop, ptr))) {
2228                 IDProperty tmp, *array;
2229                 int len;
2230
2231                 len= idprop->len;
2232                 array= IDP_IDPArray(idprop);
2233
2234                 if(key >= 0 && key < len) {
2235                         if(key+1 < len) {
2236                                 /* move element to be removed to the back */
2237                                 memcpy(&tmp, &array[key], sizeof(IDProperty));
2238                                 memmove(array+key, array+key+1, sizeof(IDProperty)*(len-(key+1)));
2239                                 memcpy(&array[len-1], &tmp, sizeof(IDProperty));
2240                         }
2241
2242                         IDP_ResizeIDPArray(idprop, len-1);
2243                 }
2244
2245                 return 1;
2246         }
2247         else if(prop->flag & PROP_IDPROPERTY)
2248                 return 1;
2249
2250         /* py api calls directly */
2251 #if 0
2252         else if(cprop->remove){
2253                 if(!(cprop->remove->flag & FUNC_USE_CONTEXT)) { /* XXX check for this somewhere else */
2254                         ParameterList params;
2255                         RNA_parameter_list_create(&params, ptr, cprop->remove);
2256                         RNA_function_call(NULL, NULL, ptr, cprop->remove, &params);
2257                         RNA_parameter_list_free(&params);
2258                 }
2259
2260                 return 0;
2261         }
2262         /*else
2263                 printf("RNA_property_collection_remove %s.%s: only supported for id properties.\n", ptr->type->identifier, prop->identifier);*/
2264 #endif
2265         return 0;
2266 }
2267
2268 int RNA_property_collection_move(PointerRNA *ptr, PropertyRNA *prop, int key, int pos)
2269 {
2270         IDProperty *idprop;
2271
2272         if((idprop=rna_idproperty_check(&prop, ptr))) {
2273                 IDProperty tmp, *array;
2274                 int len;
2275
2276                 len= idprop->len;
2277                 array= IDP_IDPArray(idprop);
2278
2279                 if(key >= 0 && key < len && pos >= 0 && pos < len && key != pos) {
2280                         memcpy(&tmp, &array[key], sizeof(IDProperty));
2281                         if(pos < key)
2282                                 memmove(array+pos+1, array+pos, sizeof(IDProperty)*(key - pos));
2283                         else
2284                                 memmove(array+key, array+key+1, sizeof(IDProperty)*(pos - key));
2285                         memcpy(&array[pos], &tmp, sizeof(IDProperty));
2286                 }
2287
2288                 return 1;
2289         }
2290         else if(prop->flag & PROP_IDPROPERTY)
2291                 return 1;
2292
2293         return 0;
2294 }
2295
2296 void RNA_property_collection_clear(PointerRNA *ptr, PropertyRNA *prop)
2297 {
2298         IDProperty *idprop;
2299
2300         if((idprop=rna_idproperty_check(&prop, ptr)))
2301                 IDP_ResizeIDPArray(idprop, 0);
2302 }
2303
2304 int RNA_property_collection_lookup_index(PointerRNA *ptr, PropertyRNA *prop, PointerRNA *t_ptr)
2305 {
2306         CollectionPropertyIterator iter;
2307         int index= 0;
2308         
2309         RNA_property_collection_begin(ptr, prop, &iter);
2310         for(index=0; iter.valid; RNA_property_collection_next(&iter), index++) {
2311                 if (iter.ptr.data == t_ptr->data)
2312                         break;
2313         }
2314         RNA_property_collection_end(&iter);
2315         
2316         /* did we find it? */
2317         if (iter.valid)
2318                 return index;
2319         else
2320                 return -1;
2321 }
2322
2323 int RNA_property_collection_lookup_int(PointerRNA *ptr, PropertyRNA *prop, int key, PointerRNA *r_ptr)
2324 {
2325         CollectionPropertyRNA *cprop= (CollectionPropertyRNA*)rna_ensure_property(prop);
2326
2327         if(cprop->lookupint) {
2328                 /* we have a callback defined, use it */
2329                 return cprop->lookupint(ptr, key, r_ptr);
2330         }
2331         else {
2332                 /* no callback defined, just iterate and find the nth item */
2333                 CollectionPropertyIterator iter;
2334                 int i;
2335
2336                 RNA_property_collection_begin(ptr, prop, &iter);
2337                 for(i=0; iter.valid; RNA_property_collection_next(&iter), i++) {
2338                         if(i == key) {
2339                                 *r_ptr= iter.ptr;
2340                                 break;
2341                         }
2342                 }
2343                 RNA_property_collection_end(&iter);
2344
2345                 if(!iter.valid)
2346                         memset(r_ptr, 0, sizeof(*r_ptr));
2347
2348                 return iter.valid;
2349         }
2350 }
2351
2352 int RNA_property_collection_lookup_string(PointerRNA *ptr, PropertyRNA *prop, const char *key, PointerRNA *r_ptr)
2353 {
2354         CollectionPropertyRNA *cprop= (CollectionPropertyRNA*)rna_ensure_property(prop);
2355
2356         if(cprop->lookupstring) {
2357                 /* we have a callback defined, use it */
2358                 return cprop->lookupstring(ptr, key, r_ptr);
2359         }
2360         else {
2361                 /* no callback defined, compare with name properties if they exist */
2362                 CollectionPropertyIterator iter;
2363                 PropertyRNA *nameprop;
2364                 char name[256], *nameptr;
2365                 int found= 0;
2366
2367                 RNA_property_collection_begin(ptr, prop, &iter);
2368                 for(; iter.valid; RNA_property_collection_next(&iter)) {
2369                         if(iter.ptr.data && iter.ptr.type->nameproperty) {
2370                                 nameprop= iter.ptr.type->nameproperty;
2371
2372                                 nameptr= RNA_property_string_get_alloc(&iter.ptr, nameprop, name, sizeof(name));
2373
2374                                 if(strcmp(nameptr, key) == 0) {
2375                                         *r_ptr= iter.ptr;
2376                                         found= 1;
2377                                 }
2378
2379                                 if((char *)&name != nameptr)
2380                                         MEM_freeN(nameptr);
2381
2382                                 if(found)
2383                                         break;
2384                         }
2385                 }
2386                 RNA_property_collection_end(&iter);
2387
2388                 if(!iter.valid)
2389                         memset(r_ptr, 0, sizeof(*r_ptr));
2390
2391                 return iter.valid;
2392         }
2393 }
2394
2395 int RNA_property_collection_type_get(PointerRNA *ptr, PropertyRNA *prop, PointerRNA *r_ptr)
2396 {
2397         *r_ptr= *ptr;
2398         return ((r_ptr->type = prop->srna) ? 1:0);
2399 }
2400
2401 int RNA_property_collection_raw_array(PointerRNA *ptr, PropertyRNA *prop, PropertyRNA *itemprop, RawArray *array)
2402 {
2403         CollectionPropertyIterator iter;
2404         ArrayIterator *internal;
2405         char *arrayp;
2406
2407         if(!(prop->flag & PROP_RAW_ARRAY) || !(itemprop->flag & PROP_RAW_ACCESS))
2408                 return 0;
2409
2410         RNA_property_collection_begin(ptr, prop, &iter);
2411
2412         if(iter.valid) {
2413                 /* get data from array iterator and item property */
2414                 internal= iter.internal;
2415                 arrayp= (iter.valid)? iter.ptr.data: NULL;
2416
2417                 if(internal->skip || !RNA_property_editable(&iter.ptr, itemprop)) {
2418                         /* we might skip some items, so it's not a proper array */
2419                         RNA_property_collection_end(&iter);
2420                         return 0;
2421                 }
2422
2423                 array->array= arrayp + itemprop->rawoffset;
2424                 array->stride= internal->itemsize;
2425                 array->len= ((char*)internal->endptr - arrayp)/internal->itemsize;
2426                 array->type= itemprop->rawtype;
2427         }
2428         else
2429                 memset(array, 0, sizeof(RawArray));
2430
2431         RNA_property_collection_end(&iter);
2432
2433         return 1;
2434 }
2435
2436 #define RAW_GET(dtype, var, raw, a) \
2437 { \
2438         switch(raw.type) { \
2439                 case PROP_RAW_CHAR: var = (dtype)((char*)raw.array)[a]; break; \
2440                 case PROP_RAW_SHORT: var = (dtype)((short*)raw.array)[a]; break; \
2441                 case PROP_RAW_INT: var = (dtype)((int*)raw.array)[a]; break; \
2442                 case PROP_RAW_FLOAT: var = (dtype)((float*)raw.array)[a]; break; \
2443                 case PROP_RAW_DOUBLE: var = (dtype)((double*)raw.array)[a]; break; \
2444                 default: var = (dtype)0; \
2445         } \
2446 }
2447
2448 #define RAW_SET(dtype, raw, a, var) \
2449 { \
2450         switch(raw.type) { \
2451                 case PROP_RAW_CHAR: ((char*)raw.array)[a] = (char)var; break; \
2452                 case PROP_RAW_SHORT: ((short*)raw.array)[a] = (short)var; break; \
2453                 case PROP_RAW_INT: ((int*)raw.array)[a] = (int)var; break; \
2454                 case PROP_RAW_FLOAT: ((float*)raw.array)[a] = (float)var; break; \
2455                 case PROP_RAW_DOUBLE: ((double*)raw.array)[a] = (double)var; break; \
2456                 default: break; \
2457         } \
2458 }
2459
2460 int RNA_raw_type_sizeof(RawPropertyType type)
2461 {
2462         switch(type) {
2463                 case PROP_RAW_CHAR: return sizeof(char);
2464                 case PROP_RAW_SHORT: return sizeof(short);
2465                 case PROP_RAW_INT: return sizeof(int);
2466                 case PROP_RAW_FLOAT: return sizeof(float);
2467                 case PROP_RAW_DOUBLE: return sizeof(double);
2468                 default: return 0;
2469         }
2470 }
2471
2472 static int rna_raw_access(ReportList *reports, PointerRNA *ptr, PropertyRNA *prop, const char *propname, void *inarray, RawPropertyType intype, int inlen, int set)
2473 {
2474         StructRNA *ptype;
2475         PointerRNA itemptr;
2476         PropertyRNA *itemprop, *iprop;
2477         PropertyType itemtype=0;
2478         RawArray in;
2479         int itemlen= 0;
2480
2481         /* initialize in array, stride assumed 0 in following code */
2482         in.array= inarray;
2483         in.type= intype;
2484         in.len= inlen;
2485         in.stride= 0;
2486
2487         ptype= RNA_property_pointer_type(ptr, prop);
2488
2489         /* try to get item property pointer */
2490         RNA_pointer_create(NULL, ptype, NULL, &itemptr);
2491         itemprop= RNA_struct_find_property(&itemptr, propname);
2492
2493         if(itemprop) {
2494                 /* we have item property pointer */
2495                 RawArray out;
2496
2497                 /* check type */
2498                 itemtype= RNA_property_type(itemprop);
2499
2500                 if(!ELEM3(itemtype, PROP_BOOLEAN, PROP_INT, PROP_FLOAT)) {
2501                         BKE_report(reports, RPT_ERROR, "Only boolean, int and float properties supported.");
2502                         return 0;
2503                 }
2504
2505                 /* check item array */
2506                 itemlen= RNA_property_array_length(&itemptr, itemprop);
2507
2508                 /* try to access as raw array */
2509                 if(RNA_property_collection_raw_array(ptr, prop, itemprop, &out)) {
2510                         int arraylen = (itemlen == 0) ? 1 : itemlen;
2511                         if(in.len != arraylen*out.len) {
2512                                 BKE_reportf(reports, RPT_ERROR, "Array length mismatch (expected %d, got %d).", out.len*arraylen, in.len);
2513                                 return 0;
2514                         }
2515                         
2516                         /* matching raw types */
2517                         if(out.type == in.type) {
2518                                 void *inp= in.array;
2519                                 void *outp= out.array;
2520                                 int a, size;
2521
2522                                 size= RNA_raw_type_sizeof(out.type) * arraylen;
2523
2524                                 for(a=0; a<out.len; a++) {
2525                                         if(set) memcpy(outp, inp, size);
2526                                         else memcpy(inp, outp, size);
2527
2528                                         inp= (char*)inp + size;
2529                                         outp= (char*)outp + out.stride;
2530                                 }
2531
2532                                 return 1;
2533                         }
2534
2535                         /* could also be faster with non-matching types,
2536                          * for now we just do slower loop .. */
2537                 }
2538         }
2539
2540         {
2541                 void *tmparray= NULL;
2542                 int tmplen= 0;
2543                 int err= 0, j, a= 0;
2544                 int needconv = 1;
2545
2546                 if (((itemtype == PROP_BOOLEAN || itemtype == PROP_INT) && in.type == PROP_RAW_INT) ||
2547                         (itemtype == PROP_FLOAT && in.type == PROP_RAW_FLOAT))
2548                         /* avoid creating temporary buffer if the data type match */
2549                         needconv = 0;
2550
2551                 /* no item property pointer, can still be id property, or
2552                  * property of a type derived from the collection pointer type */
2553                 RNA_PROP_BEGIN(ptr, itemptr, prop) {
2554                         if(itemptr.data) {
2555                                 if(itemprop) {
2556                                         /* we got the property already */
2557                                         iprop= itemprop;
2558                                 }
2559                                 else {
2560                                         /* not yet, look it up and verify if it is valid */
2561                                         iprop= RNA_struct_find_property(&itemptr, propname);
2562
2563                                         if(iprop) {
2564                                                 itemlen= RNA_property_array_length(&itemptr, iprop);
2565                                                 itemtype= RNA_property_type(iprop);
2566                                         }
2567                                         else {
2568                                                 BKE_reportf(reports, RPT_ERROR, "Property named %s not found.", propname);
2569                                                 err= 1;
2570                                                 break;
2571                                         }
2572
2573                                         if(!ELEM3(itemtype, PROP_BOOLEAN, PROP_INT, PROP_FLOAT)) {
2574                                                 BKE_report(reports, RPT_ERROR, "Only boolean, int and float properties supported.");
2575                                                 err= 1;
2576                                                 break;
2577                                         }
2578                                 }
2579
2580                                 /* editable check */
2581                                 if(RNA_property_editable(&itemptr, iprop)) {
2582                                         if(a+itemlen > in.len) {
2583                                                 BKE_reportf(reports, RPT_ERROR, "Array length mismatch (got %d, expected more).", in.len);
2584                                                 err= 1;
2585                                                 break;
2586                                         }
2587
2588                                         if(itemlen == 0) {
2589                                                 /* handle conversions */
2590                                                 if(set) {
2591                                                         switch(itemtype) {
2592                                                                 case PROP_BOOLEAN: {
2593                                                                         int b;
2594                                                                         RAW_GET(int, b, in, a);
2595                                                                         RNA_property_boolean_set(&itemptr, iprop, b);
2596                                                                         break;
2597                                                                 }
2598                                                                 case PROP_INT: {
2599                                                                         int i;
2600                                                                         RAW_GET(int, i, in, a);
2601                                                                         RNA_property_int_set(&itemptr, iprop, i);
2602                                                                         break;
2603                                                                 }
2604                                                                 case PROP_FLOAT: {
2605                                                                         float f;
2606                                                                         RAW_GET(float, f, in, a);
2607                                                                         RNA_property_float_set(&itemptr, iprop, f);
2608                                                                         break;
2609                                                                 }
2610                                                                 default:
2611                                                                         break;
2612                                                         }
2613                                                 }
2614                                                 else {
2615                                                         switch(itemtype) {
2616                                                                 case PROP_BOOLEAN: {
2617                                                                         int b= RNA_property_boolean_get(&itemptr, iprop);
2618                                                                         RAW_SET(int, in, a, b);
2619                                                                         break;
2620                                                                 }
2621                                                                 case PROP_INT: {
2622                                                                         int i= RNA_property_int_get(&itemptr, iprop);
2623                                                                         RAW_SET(int, in, a, i);
2624                                                                         break;
2625                                                                 }
2626                                                                 case PROP_FLOAT: {
2627                                                                         float f= RNA_property_float_get(&itemptr, iprop);
2628                                                                         RAW_SET(float, in, a, f);
2629                                                                         break;
2630                                                                 }
2631                                                                 default:
2632                                                                         break;
2633                                                         }
2634                                                 }
2635                                                 a++;
2636                                         }
2637                                         else if (needconv == 1) {
2638                                                 /* allocate temporary array if needed */
2639                                                 if(tmparray && tmplen != itemlen) {
2640                                                         MEM_freeN(tmparray);
2641                                                         tmparray= NULL;
2642                                                 }
2643                                                 if(!tmparray) {
2644                                                         tmparray= MEM_callocN(sizeof(float)*itemlen, "RNA tmparray\n");
2645                                                         tmplen= itemlen;
2646                                                 }
2647
2648                                                 /* handle conversions */
2649                                                 if(set) {
2650                                                         switch(itemtype) {
2651                                                                 case PROP_BOOLEAN: {
2652                                                                         for(j=0; j<itemlen; j++, a++)
2653                                                                                 RAW_GET(int, ((int*)tmparray)[j], in, a);
2654                                                                         RNA_property_boolean_set_array(&itemptr, iprop, tmparray);
2655                                                                         break;
2656                                                                 }
2657                                                                 case PROP_INT: {
2658                                                                         for(j=0; j<itemlen; j++, a++)
2659                                                                                 RAW_GET(int, ((int*)tmparray)[j], in, a);
2660                                                                         RNA_property_int_set_array(&itemptr, iprop, tmparray);
2661                                                                         break;
2662                                                                 }
2663                                                                 case PROP_FLOAT: {
2664                                                                         for(j=0; j<itemlen; j++, a++)
2665                                                                                 RAW_GET(float, ((float*)tmparray)[j], in, a);
2666                                                                         RNA_property_float_set_array(&itemptr, iprop, tmparray);
2667                                                                         break;
2668                                                                 }
2669                                                                 default:
2670                                                                         break;
2671                                                         }
2672                                                 }
2673                                                 else {
2674                                                         switch(itemtype) {
2675                                                                 case PROP_BOOLEAN: {
2676                                                                         RNA_property_boolean_get_array(&itemptr, iprop, tmparray);
2677                                                                         for(j=0; j<itemlen; j++, a++)
2678                                                                                 RAW_SET(int, in, a, ((int*)tmparray)[j]);
2679                                                                         break;
2680                                                                 }
2681                                                                 case PROP_INT: {
2682                                                                         RNA_property_int_get_array(&itemptr, iprop, tmparray);
2683                                                                         for(j=0; j<itemlen; j++, a++)
2684                                                                                 RAW_SET(int, in, a, ((int*)tmparray)[j]);
2685                                                                         break;
2686                                                                 }
2687                                                                 case PROP_FLOAT: {
2688                                                                         RNA_property_float_get_array(&itemptr, iprop, tmparray);
2689                                                                         for(j=0; j<itemlen; j++, a++)
2690                                                                                 RAW_SET(float, in, a, ((float*)tmparray)[j]);
2691                                                                         break;
2692                                                                 }
2693                                                                 default:
2694                                                                         break;
2695                                                         }
2696                                                 }
2697                                         }
2698                                         else {
2699                                                 if(set) {
2700                                                         switch(itemtype) {
2701                                                                 case PROP_BOOLEAN: {
2702                                                                         RNA_property_boolean_set_array(&itemptr, iprop, &((int*)in.array)[a]);
2703                                                                         a += itemlen;
2704                                                                         break;
2705                                                                 }
2706                                                                 case PROP_INT: {
2707                                                                         RNA_property_int_set_array(&itemptr, iprop, &((int*)in.array)[a]);
2708                                                                         a += itemlen;
2709                                                                         break;
2710                                                                 }
2711                                                                 case PROP_FLOAT: {
2712                                                                         RNA_property_float_set_array(&itemptr, iprop, &((float*)in.array)[a]);
2713                                                                         a += itemlen;
2714                                                                         break;
2715                                                                 }
2716                                                                 default:
2717                                                                         break;
2718                                                         }
2719                                                 }
2720                                                 else {
2721                                                         switch(itemtype) {
2722                                                                 case PROP_BOOLEAN: {
2723                                                                         RNA_property_boolean_get_array(&itemptr, iprop, &((int*)in.array)[a]);
2724                                                                         a += itemlen;
2725                                                                         break;
2726                                                                 }
2727                                                                 case PROP_INT: {
2728                                                                         RNA_property_int_get_array(&itemptr, iprop, &((int*)in.array)[a]);
2729                                                                         a += itemlen;
2730                                                                         break;
2731                                                                 }
2732                                                                 case PROP_FLOAT: {
2733                                                                         RNA_property_float_get_array(&itemptr, iprop, &((float*)in.array)[a]);
2734                                                                         a += itemlen;
2735                                                                         break;
2736                                                                 }
2737                                                                 default:
2738                                                                         break;
2739                                                         }
2740                                                 }
2741                                         }
2742                                 }
2743                         }
2744                 }
2745                 RNA_PROP_END;
2746
2747                 if(tmparray)
2748                         MEM_freeN(tmparray);
2749
2750                 return !err;
2751         }
2752 }
2753
2754 RawPropertyType RNA_property_raw_type(PropertyRNA *prop)
2755 {
2756         if (prop->rawtype == PROP_RAW_UNSET) {
2757                 /* this property has no raw access, yet we try to provide a raw type to help building the array */
2758                 switch (prop->type) {
2759                 case PROP_BOOLEAN:
2760                         return PROP_RAW_INT;
2761                 case PROP_INT:
2762                         return PROP_RAW_INT;
2763                 case PROP_FLOAT:
2764                         return PROP_RAW_FLOAT;
2765                 case PROP_ENUM:
2766                         return PROP_RAW_INT;
2767                 default:
2768                         break;
2769                 }
2770         }
2771         return prop->rawtype;
2772 }
2773
2774 int RNA_property_collection_raw_get(ReportList *reports, PointerRNA *ptr, PropertyRNA *prop, const char *propname, void *array, RawPropertyType type, int len)
2775 {
2776         return rna_raw_access(reports, ptr, prop, propname, array, type, len, 0);
2777 }
2778
2779 int RNA_property_collection_raw_set(ReportList *reports, PointerRNA *ptr, PropertyRNA *prop, const char *propname, void *array, RawPropertyType type, int len)
2780 {
2781         return rna_raw_access(reports, ptr, prop, propname, array, type, len, 1);
2782 }
2783
2784 /* Standard iterator functions */
2785
2786 void rna_iterator_listbase_begin(CollectionPropertyIterator *iter, ListBase *lb, IteratorSkipFunc skip)
2787 {
2788         ListBaseIterator *internal;
2789
2790         internal= MEM_callocN(sizeof(ListBaseIterator), "ListBaseIterator");
2791         internal->link= (lb)? lb->first: NULL;
2792         internal->skip= skip;
2793
2794         iter->internal= internal;
2795         iter->valid= (internal->link != NULL);
2796
2797         if(skip && iter->valid && skip(iter, internal->link))
2798                 rna_iterator_listbase_next(iter);
2799 }
2800
2801 void rna_iterator_listbase_next(CollectionPropertyIterator *iter)
2802 {
2803         ListBaseIterator *internal= iter->internal;
2804
2805         if(internal->skip) {
2806                 do {
2807                         internal->link= internal->link->next;
2808                         iter->valid= (internal->link != NULL);
2809                 } while(iter->valid && internal->skip(iter, internal->link));
2810         }
2811         else {
2812                 internal->link= internal->link->next;
2813                 iter->valid= (internal->link != NULL);
2814         }
2815 }
2816
2817 void *rna_iterator_listbase_get(CollectionPropertyIterator *iter)
2818 {
2819         ListBaseIterator *internal= iter->internal;
2820
2821         return internal->link;
2822 }
2823
2824 void rna_iterator_listbase_end(CollectionPropertyIterator *iter)
2825 {
2826         MEM_freeN(iter->internal);
2827         iter->internal= NULL;
2828 }
2829
2830 PointerRNA rna_listbase_lookup_int(PointerRNA *ptr, StructRNA *type, struct ListBase *lb, int index)
2831 {
2832         void *data= BLI_findlink(lb, index);
2833         return rna_pointer_inherit_refine(ptr, type, data);
2834 }
2835
2836 void rna_iterator_array_begin(CollectionPropertyIterator *iter, void *ptr, int itemsize, int length, int free_ptr, IteratorSkipFunc skip)
2837 {
2838         ArrayIterator *internal;
2839
2840         if(ptr == NULL)
2841                 length= 0;
2842         else if (length == 0) {
2843                 ptr= NULL;
2844                 itemsize= 0;
2845         }
2846
2847         internal= MEM_callocN(sizeof(ArrayIterator), "ArrayIterator");
2848         internal->ptr= ptr;
2849         internal->free_ptr= free_ptr ? ptr:NULL;
2850         internal->endptr= ((char*)ptr)+length*itemsize;
2851         internal->itemsize= itemsize;
2852         internal->skip= skip;
2853         internal->length= length;
2854         
2855         iter->internal= internal;
2856         iter->valid= (internal->ptr != internal->endptr);
2857
2858         if(skip && iter->valid && skip(iter, internal->ptr))
2859                 rna_iterator_array_next(iter);
2860 }
2861
2862 void rna_iterator_array_next(CollectionPropertyIterator *iter)
2863 {
2864         ArrayIterator *internal= iter->internal;
2865
2866         if(internal->skip) {
2867                 do {
2868                         internal->ptr += internal->itemsize;
2869                         iter->valid= (internal->ptr != internal->endptr);
2870                 } while(iter->valid && internal->skip(iter, internal->ptr));
2871         }
2872         else {
2873                 internal->ptr += internal->itemsize;
2874                 iter->valid= (internal->ptr != internal->endptr);
2875         }
2876 }
2877
2878 void *rna_iterator_array_get(CollectionPropertyIterator *iter)
2879 {
2880         ArrayIterator *internal= iter->internal;
2881
2882         return internal->ptr;
2883 }
2884
2885 void *rna_iterator_array_dereference_get(CollectionPropertyIterator *iter)
2886 {
2887         ArrayIterator *internal= iter->internal;
2888
2889         /* for ** arrays */
2890         return *(void**)(internal->ptr);
2891 }
2892
2893 void rna_iterator_array_end(CollectionPropertyIterator *iter)
2894 {
2895         ArrayIterator *internal= iter->internal;
2896         
2897         if(internal->free_ptr) {
2898                 MEM_freeN(internal->free_ptr);
2899                 internal->free_ptr= NULL;
2900         }
2901         MEM_freeN(iter->internal);
2902         iter->internal= NULL;
2903 }
2904
2905 PointerRNA rna_array_lookup_int(PointerRNA *ptr, StructRNA *type, void *data, int itemsize, int length, int index)
2906 {
2907         if(index < 0 || index >= length)
2908                 return PointerRNA_NULL;
2909
2910         return rna_pointer_inherit_refine(ptr, type, ((char*)data) + index*itemsize);
2911 }
2912
2913 /* RNA Path - Experiment */
2914
2915 static char *rna_path_token(const char **path, char *fixedbuf, int fixedlen, int bracket)
2916 {
2917         const char *p;
2918         char *buf;
2919         char quote= '\0';
2920         int i, j, len, escape;
2921
2922         len= 0;
2923
2924         if(bracket) {
2925                 /* get data between [], check escaping ] with \] */
2926                 if(**path == '[') (*path)++;
2927                 else return NULL;
2928
2929                 p= *path;
2930
2931                 /* 2 kinds of lookups now, quoted or unquoted */
2932                 quote= *p;
2933
2934                 if(quote != '"')
2935                         quote= 0;
2936
2937                 if(quote==0) {
2938                         while(*p && (*p != ']')) {
2939                                 len++;
2940                                 p++;
2941                         }
2942                 }
2943                 else {
2944                         escape= 0;
2945                         /* skip the first quote */
2946                         len++;
2947                         p++;
2948                         while(*p && (*p != quote || escape)) {
2949                                 escape= (*p == '\\');
2950                                 len++;
2951                                 p++;
2952                         }
2953                         
2954                         /* skip the last quoted char to get the ']' */
2955                         len++;
2956                         p++;
2957                 }
2958
2959                 if(*p != ']') return NULL;
2960         }
2961         else {
2962                 /* get data until . or [ */
2963                 p= *path;
2964
2965                 while(*p && *p != '.' && *p != '[') {
2966                         len++;
2967                         p++;
2968                 }
2969         }
2970         
2971         /* empty, return */
2972         if(len == 0)
2973                 return NULL;
2974         
2975         /* try to use fixed buffer if possible */
2976         if(len+1 < fixedlen)
2977                 buf= fixedbuf;
2978         else
2979                 buf= MEM_callocN(sizeof(char)*(len+1), "rna_path_token");
2980
2981         /* copy string, taking into account escaped ] */
2982         if(bracket) {
2983                 for(p=*path, i=0, j=0; i<len; i++, p++) {
2984                         if(*p == '\\' && *(p+1) == quote);
2985                         else buf[j++]= *p;
2986                 }
2987
2988                 buf[j]= 0;
2989         }
2990         else {
2991                 memcpy(buf, *path, sizeof(char)*len);
2992                 buf[len]= '\0';
2993         }
2994
2995         /* set path to start of next token */
2996         if(*p == ']') p++;
2997         if(*p == '.') p++;
2998         *path= p;
2999
3000         return buf;
3001 }
3002
3003 static int rna_token_strip_quotes(char *token)
3004 {
3005         if(token[0]=='"') {
3006                 int len = strlen(token);
3007                 if (len >= 2 && token[len-1]=='"') {
3008                         /* strip away "" */
3009                         token[len-1]= '\0';
3010                         return 1;
3011                 }
3012         }
3013         return 0;
3014 }
3015
3016 /* Resolve the given RNA path to find the pointer+property indicated at the end of the path */
3017 int RNA_path_resolve(PointerRNA *ptr, const char *path, PointerRNA *r_ptr, PropertyRNA **r_prop)
3018 {
3019         return RNA_path_resolve_full(ptr, path, r_ptr, r_prop, NULL);
3020 }
3021
3022 int RNA_path_resolve_full(PointerRNA *ptr, const char *path, PointerRNA *r_ptr, PropertyRNA **r_prop, int *index)
3023 {
3024         PropertyRNA *prop;
3025         PointerRNA curptr, nextptr;
3026         char fixedbuf[256], *token;
3027         int type, intkey;
3028
3029         prop= NULL;
3030         curptr= *ptr;
3031
3032         if(path==NULL || *path=='\0')
3033                 return 0;
3034
3035         while(*path) {
3036                 int use_id_prop = (*path=='[') ? 1:0;
3037                 /* custom property lookup ?
3038                  * C.object["someprop"]
3039                  */
3040
3041                 /* look up property name in current struct */
3042                 token= rna_path_token(&path, fixedbuf, sizeof(fixedbuf), use_id_prop);
3043
3044                 if(!token)
3045                         return 0;
3046
3047                 if(use_id_prop) { /* look up property name in current struct */
3048                         IDProperty *group= RNA_struct_idprops(&curptr, 0);
3049                         if(group && rna_token_strip_quotes(token))
3050                                 prop= (PropertyRNA *)IDP_GetPropertyFromGroup(group, token+1);
3051                 }
3052                 else {
3053                         prop= RNA_struct_find_property(&curptr, token);
3054                 }
3055
3056                 if(token != fixedbuf)
3057                         MEM_freeN(token);
3058
3059                 if(!prop)
3060                         return 0;
3061
3062                 type= RNA_property_type(prop);
3063
3064                 /* now look up the value of this property if it is a pointer or
3065                  * collection, otherwise return the property rna so that the
3066                  * caller can read the value of the property itself */
3067                 switch (type) {
3068                 case PROP_POINTER:
3069                         nextptr= RNA_property_pointer_get(&curptr, prop);
3070
3071                         if(nextptr.data) {
3072                                 curptr= nextptr;
3073                                 prop= NULL; /* now we have a PointerRNA, the prop is our parent so forget it */
3074                                 if(index) *index= -1;
3075                         }
3076                         else
3077                                 return 0;
3078
3079                         break;
3080                 case PROP_COLLECTION:
3081                         if(*path) {
3082                                 if(*path == '[') {
3083                                         /* resolve the lookup with [] brackets */
3084                                         token= rna_path_token(&path, fixedbuf, sizeof(fixedbuf), 1);
3085         
3086                                         if(!token)
3087                                                 return 0;
3088         
3089                                         /* check for "" to see if it is a string */
3090                                         if(rna_token_strip_quotes(token)) {
3091                                                 RNA_property_collection_lookup_string(&curptr, prop, token+1, &nextptr);
3092                                         }
3093                                         else {
3094                                                 /* otherwise do int lookup */
3095                                                 intkey= atoi(token);
3096                                                 if(intkey==0 && (token[0] != '0' || token[1] != '\0')) {
3097                                                         return 0; /* we can be sure the fixedbuf was used in this case */
3098                                                 }
3099                                                 RNA_property_collection_lookup_int(&curptr, prop, intkey, &nextptr);
3100                                         }
3101
3102                                         if(token != fixedbuf) {
3103                                                 MEM_freeN(token);
3104                                         }
3105                                 }
3106                                 else {
3107                                         PointerRNA c_ptr;
3108                                         
3109                                         /* ensure we quit on invalid values */
3110                                         nextptr.data = NULL;
3111
3112                                         if(RNA_property_collection_type_get(&curptr, prop, &c_ptr)) {
3113                                                 nextptr= c_ptr;
3114                                         }
3115                                 }
3116
3117                                 if(nextptr.data) {
3118                                         curptr= nextptr;
3119                                         prop= NULL;  /* now we have a PointerRNA, the prop is our parent so forget it */
3120                                         if(index) *index= -1;
3121                                 }
3122                                 else
3123                                         return 0;
3124                         }
3125                         
3126                         break;
3127                 default:
3128                         if (index==NULL)
3129                                 break;
3130
3131                         *index= -1;
3132
3133                         if (*path) {
3134                                 int index_arr[RNA_MAX_ARRAY_DIMENSION]= {0};
3135                                 int len[RNA_MAX_ARRAY_DIMENSION];
3136                                 const int dim= RNA_property_array_dimension(&curptr, prop, len);
3137                                 int i, temp_index;
3138
3139                                 for(i=0; i<dim; i++) {
3140                                         temp_index= -1; 
3141
3142                                         /* multi index resolve */
3143                                         if (*path=='[') {
3144                                                 token= rna_path_token(&path, fixedbuf, sizeof(fixedbuf), 1);
3145         
3146                                                 if(token==NULL) {
3147                                                         /* invalid syntax blah[] */
3148                                                         return 0;
3149                                                 }
3150                                                 /* check for "" to see if it is a string */
3151                                                 else if(rna_token_strip_quotes(token)) {
3152                                                         temp_index= RNA_property_array_item_index(prop, *(token+1));
3153                                                 }
3154                                                 else {
3155                                                         /* otherwise do int lookup */
3156                                                         temp_index= atoi(token);
3157
3158                                                         if(temp_index==0 && (token[0] != '0' || token[1] != '\0')) {
3159                                                                 if(token != fixedbuf) {
3160                                                                         MEM_freeN(token);
3161                                                                 }
3162
3163                                                                 return 0;
3164                                                         }
3165                                                 }
3166                                         }
3167                                         else if(dim==1) {
3168                                                 /* location.x || scale.X, single dimension arrays only */
3169                                                 token= rna_path_token(&path, fixedbuf, sizeof(fixedbuf), 0);
3170                                                 if(token==NULL) {
3171                                                         /* invalid syntax blah.. */
3172                                                         return 0;
3173                                                 }
3174                                                 temp_index= RNA_property_array_item_index(prop, *token);
3175                                         }
3176         
3177                                         if(token != fixedbuf) {
3178                                                 MEM_freeN(token);
3179                                         }
3180                                         
3181                                         /* out of range */
3182                                         if(temp_index < 0 || temp_index >= len[i])
3183                                                 return 0;
3184
3185                                         index_arr[i]= temp_index;