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