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