Blender V4.3
rna_access.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2023 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
9#include <cctype>
10#include <cstddef>
11#include <cstdlib>
12#include <cstring>
13#include <sstream>
14
15#include <fmt/format.h>
16
17#include "MEM_guardedalloc.h"
18
19#include "DNA_ID.h"
20#include "DNA_anim_types.h"
22#include "DNA_modifier_types.h"
23#include "DNA_scene_types.h"
25
26#include "BLI_alloca.h"
27#include "BLI_blenlib.h"
28#include "BLI_dynstr.h"
29#include "BLI_ghash.h"
30#include "BLI_threads.h"
31#include "BLI_utildefines.h"
32
33#include "BLF_api.hh"
34#include "BLT_translation.hh"
35
36#include "BKE_anim_data.hh"
37#include "BKE_collection.hh"
38#include "BKE_context.hh"
39#include "BKE_fcurve.hh"
40#include "BKE_global.hh"
41#include "BKE_idprop.hh"
42#include "BKE_idtype.hh"
43#include "BKE_lib_id.hh"
44#include "BKE_lib_override.hh"
45#include "BKE_main.hh"
46#include "BKE_node.hh"
47#include "BKE_report.hh"
48
49#include "CLG_log.h"
50
51#include "DEG_depsgraph.hh"
53
54#include "RNA_access.hh"
55#include "RNA_define.hh"
56#include "RNA_enum_types.hh"
57#include "RNA_path.hh"
58
59#include "WM_api.hh"
60#include "WM_message.hh"
61
62/* flush updates */
63#include "DNA_object_types.h"
64#include "WM_types.hh"
65
67#include "rna_internal.hh"
68
69static CLG_LogRef LOG = {"rna.access"};
70
71/* Init/Exit */
72
74{
75 StructRNA *srna;
76
79
80 for (srna = static_cast<StructRNA *>(BLENDER_RNA.structs.first); srna;
81 srna = static_cast<StructRNA *>(srna->cont.next))
82 {
83 if (!srna->cont.prophash) {
84 srna->cont.prophash = BLI_ghash_str_new("RNA_init gh");
85
87 if (!(prop->flag_internal & PROP_INTERN_BUILTIN)) {
88 BLI_ghash_insert(srna->cont.prophash, (void *)prop->identifier, prop);
89 }
90 }
91 }
95 }
96}
97
99{
100 StructRNA *srna;
101
102 for (srna = static_cast<StructRNA *>(BLENDER_RNA.structs.first); srna;
103 srna = static_cast<StructRNA *>(srna->cont.next))
104 {
105 if (srna->cont.prophash) {
106 BLI_ghash_free(srna->cont.prophash, nullptr, nullptr);
107 srna->cont.prophash = nullptr;
108 }
109 }
110
112}
113
114/* Pointer */
115
117{
119 ptr.owner_id = nullptr;
120 ptr.type = &RNA_BlendData;
121 ptr.data = main;
122 return ptr;
123}
124
126{
127 StructRNA *type, *idtype = nullptr;
128
129 if (id) {
130 PointerRNA tmp = {nullptr};
131 tmp.data = id;
132 idtype = rna_ID_refine(&tmp);
133
134 while (idtype->refine) {
135 type = idtype->refine(&tmp);
136
137 if (type == idtype) {
138 break;
139 }
140 idtype = type;
141 }
142 }
143
145 ptr.owner_id = id;
146 ptr.type = idtype;
147 ptr.data = id;
148 return ptr;
149}
150
152{
153#if 0 /* UNUSED */
154 StructRNA *idtype = nullptr;
155
156 if (id) {
157 PointerRNA tmp = {0};
158 tmp.data = id;
159 idtype = rna_ID_refine(&tmp);
160 }
161#endif
162
164 ptr.owner_id = id;
165 ptr.type = type;
166 ptr.data = data;
167
168 if (data) {
169 while (ptr.type && ptr.type->refine) {
170 StructRNA *rtype = ptr.type->refine(&ptr);
171
172 if (rtype == ptr.type) {
173 break;
174 }
175 ptr.type = rtype;
176 }
177 }
178
179 return ptr;
180}
181
183{
184 return (ptr->data == nullptr) || (ptr->owner_id == nullptr) || (ptr->type == nullptr);
185}
186
187static void rna_pointer_inherit_id(const StructRNA *type,
188 const PointerRNA *parent,
190{
191 if (type && type->flag & STRUCT_ID) {
192 ptr->owner_id = static_cast<ID *>(ptr->data);
193 }
194 else {
195 ptr->owner_id = parent->owner_id;
196 }
197}
198
200{
202 ptr.owner_id = nullptr;
203 ptr.type = &RNA_BlenderRNA;
205 return ptr;
206}
207
209{
210 if (data) {
212 result.data = data;
213 result.type = type;
214 rna_pointer_inherit_id(type, ptr, &result);
215
216 while (result.type->refine) {
217 type = result.type->refine(&result);
218
219 if (type == result.type) {
220 break;
221 }
222 result.type = type;
223 }
224 return result;
225 }
226 return PointerRNA_NULL;
227}
228
230{
231#if 0 /* works but this case if covered by more general code below. */
232 if (RNA_struct_is_ID(ptr->type)) {
233 /* simple case */
235 }
236 else
237#endif
238 {
239 PointerRNA r_ptr;
240 StructRNA *base;
241 PointerRNA t_ptr;
242 r_ptr = *ptr; /* initialize as the same in case can't recast */
243
244 for (base = ptr->type->base; base; base = base->base) {
245 t_ptr = rna_pointer_inherit_refine(ptr, base, ptr->data);
246 if (t_ptr.type && t_ptr.type != ptr->type) {
247 r_ptr = t_ptr;
248 }
249 }
250 return r_ptr;
251 }
252}
253
254/* ID Properties */
255
257{
258 /* so the property is seen as 'set' by rna */
259 idprop->flag &= ~IDP_FLAG_GHOST;
260}
261
263{
264 StructRNA *type = ptr->type;
265 if (type == nullptr) {
266 return nullptr;
267 }
268 if (type->idproperties == nullptr) {
269 return nullptr;
270 }
271
272 return type->idproperties(ptr);
273}
274
276{
277 IDProperty **property_ptr = RNA_struct_idprops_p(ptr);
278 if (property_ptr == nullptr) {
279 return nullptr;
280 }
281
282 if (create && *property_ptr == nullptr) {
283 *property_ptr = blender::bke::idprop::create_group(__func__, IDP_FLAG_STATIC_TYPE).release();
284 }
285
286 return *property_ptr;
287}
288
290{
291 return (srna && srna->idproperties);
292}
293
295{
296 IDProperty *group = RNA_struct_idprops(ptr, false);
297
298 if (group) {
299 if (group->type == IDP_GROUP) {
300 return IDP_GetPropertyFromGroup(group, name);
301 }
302 /* Not sure why that happens sometimes, with nested properties... */
303 /* Seems to be actually array prop, name is usually "0"... To be sorted out later. */
304#if 0
305 printf("Got unexpected IDProp container when trying to retrieve %s: %d\n", name, group->type);
306#endif
307 }
308
309 return nullptr;
310}
311
312static void rna_idproperty_free(PointerRNA *ptr, const char *name)
313{
314 IDProperty *group = RNA_struct_idprops(ptr, false);
315
316 if (group) {
317 IDProperty *idprop = IDP_GetPropertyFromGroup(group, name);
318 if (idprop) {
319 IDP_FreeFromGroup(group, idprop);
320 }
321 }
322}
323
325{
326 if (prop->magic == RNA_MAGIC) {
327 int arraylen[RNA_MAX_ARRAY_DIMENSION];
328 return (prop->getlength && ptr->data) ? prop->getlength(ptr, arraylen) :
329 int(prop->totarraylength);
330 }
331 IDProperty *idprop = (IDProperty *)prop;
332
333 if (idprop->type == IDP_ARRAY) {
334 return idprop->len;
335 }
336 return 0;
337}
338
340{
341 if (prop->magic == RNA_MAGIC) {
342 return (prop->getlength || prop->totarraylength);
343 }
344 IDProperty *idprop = (IDProperty *)prop;
345
346 return (idprop->type == IDP_ARRAY);
347}
348
350 PropertyRNA *prop,
351 int length[])
352{
353 if (prop->magic == RNA_MAGIC) {
354 if (prop->getlength) {
355 prop->getlength(ptr, length);
356 }
357 else {
358 memcpy(length, prop->arraylength, prop->arraydimension * sizeof(int));
359 }
360 }
361 else {
362 IDProperty *idprop = (IDProperty *)prop;
363
364 if (idprop->type == IDP_ARRAY) {
365 length[0] = idprop->len;
366 }
367 else {
368 length[0] = 0;
369 }
370 }
371}
372
374{
375 /* this verifies if the idproperty actually matches the property
376 * description and otherwise removes it. this is to ensure that
377 * rna property access is type safe, e.g. if you defined the rna
378 * to have a certain array length you can count on that staying so */
379
380 switch (idprop->type) {
381 case IDP_IDPARRAY:
382 if (prop->type != PROP_COLLECTION) {
383 return false;
384 }
385 break;
386 case IDP_ARRAY:
387 if (rna_ensure_property_array_length(ptr, prop) != idprop->len) {
388 return false;
389 }
390
391 if (idprop->subtype == IDP_FLOAT && prop->type != PROP_FLOAT) {
392 return false;
393 }
394 if (idprop->subtype == IDP_BOOLEAN && prop->type != PROP_BOOLEAN) {
395 return false;
396 }
397 if (idprop->subtype == IDP_INT && !ELEM(prop->type, PROP_BOOLEAN, PROP_INT, PROP_ENUM)) {
398 return false;
399 }
400
401 break;
402 case IDP_INT:
403 if (!ELEM(prop->type, PROP_BOOLEAN, PROP_INT, PROP_ENUM)) {
404 return false;
405 }
406 break;
407 case IDP_BOOLEAN:
408 if (prop->type != PROP_BOOLEAN) {
409 return false;
410 }
411 break;
412 case IDP_FLOAT:
413 case IDP_DOUBLE:
414 if (prop->type != PROP_FLOAT) {
415 return false;
416 }
417 break;
418 case IDP_STRING:
419 if (prop->type != PROP_STRING) {
420 return false;
421 }
422 break;
423 case IDP_GROUP:
424 case IDP_ID:
425 if (prop->type != PROP_POINTER) {
426 return false;
427 }
428 break;
429 default:
430 return false;
431 }
432
433 return true;
434}
435
437 &rna_PropertyGroupItem_string,
438 &rna_PropertyGroupItem_int,
439 &rna_PropertyGroupItem_float,
440 nullptr,
441 nullptr,
442 nullptr,
443 &rna_PropertyGroupItem_group,
444 &rna_PropertyGroupItem_id,
445 &rna_PropertyGroupItem_double,
446 &rna_PropertyGroupItem_idp_array,
447 &rna_PropertyGroupItem_bool,
448};
449
451 nullptr,
452 &rna_PropertyGroupItem_int_array,
453 &rna_PropertyGroupItem_float_array,
454 nullptr,
455 nullptr,
456 nullptr,
457 &rna_PropertyGroupItem_collection,
458 nullptr,
459 &rna_PropertyGroupItem_double_array,
460 nullptr,
461 &rna_PropertyGroupItem_bool_array,
462};
463
466 PropertyRNAOrID *r_prop_rna_or_id)
467{
468 /* This is quite a hack, but avoids some complexity in the API. we
469 * pass IDProperty structs as PropertyRNA pointers to the outside.
470 * We store some bytes in PropertyRNA structs that allows us to
471 * distinguish it from IDProperty structs. If it is an ID property,
472 * we look up an IDP PropertyRNA based on the type, and set the data
473 * pointer to the IDProperty. */
474 *r_prop_rna_or_id = {};
475
476 r_prop_rna_or_id->ptr = *ptr;
477 r_prop_rna_or_id->rawprop = prop;
478
479 if (prop->magic == RNA_MAGIC) {
480 r_prop_rna_or_id->rnaprop = prop;
481 r_prop_rna_or_id->identifier = prop->identifier;
482
483 r_prop_rna_or_id->is_array = prop->getlength || prop->totarraylength;
484 if (r_prop_rna_or_id->is_array) {
485 int arraylen[RNA_MAX_ARRAY_DIMENSION];
486 r_prop_rna_or_id->array_len = (prop->getlength && ptr->data) ?
487 uint(prop->getlength(ptr, arraylen)) :
488 prop->totarraylength;
489 }
490
491 if (prop->flag & PROP_IDPROPERTY) {
493
494 if (idprop != nullptr && !rna_idproperty_verify_valid(ptr, prop, idprop)) {
495 IDProperty *group = RNA_struct_idprops(ptr, false);
496
497 IDP_FreeFromGroup(group, idprop);
498 idprop = nullptr;
499 }
500
501 r_prop_rna_or_id->idprop = idprop;
502 r_prop_rna_or_id->is_rna_storage_idprop = true;
503 r_prop_rna_or_id->is_set = idprop != nullptr && (idprop->flag & IDP_FLAG_GHOST) == 0;
504 }
505 else {
506 /* Full static RNA properties are always set. */
507 r_prop_rna_or_id->is_set = true;
508 }
509 }
510 else {
511 IDProperty *idprop = (IDProperty *)prop;
512 /* Given prop may come from the custom properties of another data, ensure we get the one from
513 * given data ptr. */
514 IDProperty *idprop_evaluated = rna_idproperty_find(ptr, idprop->name);
515 if (idprop_evaluated != nullptr && idprop->type != idprop_evaluated->type) {
516 idprop_evaluated = nullptr;
517 }
518
519 r_prop_rna_or_id->idprop = idprop_evaluated;
520 r_prop_rna_or_id->is_idprop = true;
521 /* Full IDProperties are always set, if it exists. */
522 r_prop_rna_or_id->is_set = (idprop_evaluated != nullptr);
523
524 r_prop_rna_or_id->identifier = idprop->name;
525 if (idprop->type == IDP_ARRAY) {
526 r_prop_rna_or_id->rnaprop = arraytypemap[int(idprop->subtype)];
527 r_prop_rna_or_id->is_array = true;
528 r_prop_rna_or_id->array_len = idprop_evaluated != nullptr ? uint(idprop_evaluated->len) : 0;
529 }
530 else {
531 /* Special case for int properties with enum items, these are displayed as a PROP_ENUM. */
532 if (idprop->type == IDP_INT) {
533 const IDPropertyUIDataInt *ui_data_int = reinterpret_cast<IDPropertyUIDataInt *>(
534 idprop->ui_data);
535 if (ui_data_int && ui_data_int->enum_items_num > 0) {
536 r_prop_rna_or_id->rnaprop = &rna_PropertyGroupItem_enum;
537 return;
538 }
539 }
540 r_prop_rna_or_id->rnaprop = typemap[int(idprop->type)];
541 }
542 }
543}
544
546{
547 PropertyRNAOrID prop_rna_or_id;
548
549 rna_property_rna_or_id_get(*prop, ptr, &prop_rna_or_id);
550
551 *prop = prop_rna_or_id.rnaprop;
552 return prop_rna_or_id.idprop;
553}
554
556{
557 /* the quick version if we don't need the idproperty */
558
559 if (prop->magic == RNA_MAGIC) {
560 return prop;
561 }
562
563 {
564 IDProperty *idprop = (IDProperty *)prop;
565
566 if (idprop->type == IDP_ARRAY) {
567 return arraytypemap[int(idprop->subtype)];
568 }
569 /* Special case for int properties with enum items, these are displayed as a PROP_ENUM. */
570 if (idprop->type == IDP_INT) {
571 const IDPropertyUIDataInt *ui_data_int = reinterpret_cast<IDPropertyUIDataInt *>(
572 idprop->ui_data);
573 if (ui_data_int && ui_data_int->enum_items_num > 0) {
574 return &rna_PropertyGroupItem_enum;
575 }
576 }
577 return typemap[int(idprop->type)];
578 }
579}
580
581static const char *rna_ensure_property_identifier(const PropertyRNA *prop)
582{
583 if (prop->magic == RNA_MAGIC) {
584 return prop->identifier;
585 }
586 return ((const IDProperty *)prop)->name;
587}
588
589static const char *rna_ensure_property_description(const PropertyRNA *prop)
590{
591 if (prop->magic == RNA_MAGIC) {
592 return prop->description;
593 }
594
595 const IDProperty *idprop = (const IDProperty *)prop;
596 if (idprop->ui_data) {
597 const IDPropertyUIData *ui_data = idprop->ui_data;
598 return ui_data->description;
599 }
600
601 return "";
602}
603
604static const char *rna_ensure_property_name(const PropertyRNA *prop)
605{
606 const char *name;
607
608 if (prop->magic == RNA_MAGIC) {
609 name = prop->name;
610 }
611 else {
612 name = ((const IDProperty *)prop)->name;
613 }
614
615 return name;
616}
617
618/* Structs */
619
620StructRNA *RNA_struct_find(const char *identifier)
621{
622 return static_cast<StructRNA *>(BLI_ghash_lookup(BLENDER_RNA.structs_map, identifier));
623}
624
625const char *RNA_struct_identifier(const StructRNA *type)
626{
627 return type->identifier;
628}
629
630const char *RNA_struct_ui_name(const StructRNA *type)
631{
632 return CTX_IFACE_(type->translation_context, type->name);
633}
634
635const char *RNA_struct_ui_name_raw(const StructRNA *type)
636{
637 return type->name;
638}
639
641{
642 if (type) {
643 return type->icon;
644 }
645 return ICON_DOT;
646}
647
648const char *RNA_struct_ui_description(const StructRNA *type)
649{
650 return TIP_(type->description);
651}
652
654{
655 return type->description;
656}
657
659{
660 return type->translation_context;
661}
662
664{
665 return type->nameproperty;
666}
667
669{
670 return type->prop_tag_defines;
671}
672
674{
675 return type->iteratorproperty;
676}
677
679{
680 return type->base;
681}
682
683const StructRNA *RNA_struct_base_child_of(const StructRNA *type, const StructRNA *parent_type)
684{
685 while (type) {
686 if (type->base == parent_type) {
687 return type;
688 }
689 type = type->base;
690 }
691 return nullptr;
692}
693
695{
696 return (type->flag & STRUCT_ID) != 0;
697}
698
700{
701 return (type->flag & STRUCT_UNDO) != 0;
702}
703
705{
706 return (type->flag & STRUCT_NO_IDPROPERTIES) == 0;
707}
708
713
715{
716 return (type->flag & (STRUCT_CONTAINS_DATABLOCK_IDPROPERTIES | STRUCT_ID)) != 0;
717}
718
719bool RNA_struct_idprops_unset(PointerRNA *ptr, const char *identifier)
720{
721 IDProperty *group = RNA_struct_idprops(ptr, false);
722
723 if (group) {
724 IDProperty *idp = IDP_GetPropertyFromGroup(group, identifier);
725 if (idp) {
726 IDP_FreeFromGroup(group, idp);
727
728 return true;
729 }
730 }
731 return false;
732}
733
734bool RNA_struct_is_a(const StructRNA *type, const StructRNA *srna)
735{
736 const StructRNA *base;
737
738 if (srna == &RNA_AnyType) {
739 return true;
740 }
741
742 if (!type) {
743 return false;
744 }
745
746 /* ptr->type is always maximally refined */
747 for (base = type; base; base = base->base) {
748 if (base == srna) {
749 return true;
750 }
751 }
752
753 return false;
754}
755
757{
758 if (identifier[0] == '[' && identifier[1] == '"') {
759 /* id prop lookup, not so common */
760 PropertyRNA *r_prop = nullptr;
761 PointerRNA r_ptr; /* only support single level props */
762 if (RNA_path_resolve_property(ptr, identifier, &r_ptr, &r_prop) && (r_ptr.type == ptr->type) &&
763 (r_ptr.data == ptr->data))
764 {
765 return r_prop;
766 }
767 }
768 else {
769 /* most common case */
771 PointerRNA propptr;
772
773 if (RNA_property_collection_lookup_string(ptr, iterprop, identifier, &propptr)) {
774 return static_cast<PropertyRNA *>(propptr.data);
775 }
776 }
777
778 return nullptr;
779}
780
781static const char *rna_property_type_identifier(PropertyType prop_type)
782{
783 switch (prop_type) {
784 case PROP_BOOLEAN:
785 return RNA_struct_identifier(&RNA_BoolProperty);
786 case PROP_INT:
787 return RNA_struct_identifier(&RNA_IntProperty);
788 case PROP_FLOAT:
789 return RNA_struct_identifier(&RNA_FloatProperty);
790 case PROP_STRING:
791 return RNA_struct_identifier(&RNA_StringProperty);
792 case PROP_ENUM:
793 return RNA_struct_identifier(&RNA_EnumProperty);
794 case PROP_POINTER:
795 return RNA_struct_identifier(&RNA_PointerProperty);
796 case PROP_COLLECTION:
797 return RNA_struct_identifier(&RNA_CollectionProperty);
798 default:
799 return RNA_struct_identifier(&RNA_Property);
800 }
801}
802
804 const char *name,
805 const PropertyType property_type_check)
806{
807 PropertyRNA *prop = RNA_struct_find_property(&props, name);
808 if (!prop) {
809 return nullptr;
810 }
811 const PropertyType prop_type = RNA_property_type(prop);
812 if (prop_type == property_type_check) {
813 return prop;
814 }
815 CLOG_WARN(&LOG,
816 "'%s : %s()' expected, got '%s : %s()'",
817 name,
818 rna_property_type_identifier(property_type_check),
819 name,
821 return nullptr;
822}
823
825 const char *name,
826 const StructRNA *struct_type_check)
827{
828 PropertyRNA *prop = RNA_struct_find_property(&props, name);
829 if (!prop) {
830 return nullptr;
831 }
832
833 const PropertyType prop_type = RNA_property_type(prop);
834 const StructRNA *prop_struct_type = RNA_property_pointer_type(&props, prop);
835 if (prop_type == PROP_COLLECTION && prop_struct_type == struct_type_check) {
836 return prop;
837 }
838
839 if (prop_type != PROP_COLLECTION) {
840 CLOG_WARN(&LOG,
841 "'%s : %s(type = %s)' expected, got '%s : %s()'",
842 name,
844 RNA_struct_identifier(struct_type_check),
845 name,
847 return nullptr;
848 }
849
850 CLOG_WARN(&LOG,
851 "'%s : %s(type = %s)' expected, got '%s : %s(type = %s)'.",
852 name,
854 RNA_struct_identifier(struct_type_check),
855 name,
857 RNA_struct_identifier(prop_struct_type));
858 return nullptr;
859}
860
862{
863 PropertyRNA *prop = nullptr;
864
865 RNA_STRUCT_BEGIN (ptr, iprop) {
866 /* This assumes that there can only be one user of this nested struct */
867 if (RNA_property_pointer_type(ptr, iprop) == srna) {
868 prop = iprop;
869 break;
870 }
871 }
873
874 return prop;
875}
876
878{
879 /* NOTE: prop_test could be freed memory, only use for comparison. */
880
881 /* validate the RNA is ok */
882 PropertyRNA *iterprop;
883 bool found = false;
884
886
887 RNA_PROP_BEGIN (ptr, itemptr, iterprop) {
888 // PropertyRNA *prop = itemptr.data;
889 if (prop_test == (PropertyRNA *)itemptr.data) {
890 found = true;
891 break;
892 }
893 }
895
896 return found;
897}
898
900{
901 uint counter = 0;
902
903 PointerRNA struct_ptr = RNA_pointer_create(nullptr, srna, nullptr);
904
905 RNA_STRUCT_BEGIN (&struct_ptr, prop) {
906 counter++;
907 UNUSED_VARS(prop);
908 }
910
911 return counter;
912}
913
915{
916 return &srna->cont.properties;
917}
918
920{
921 return static_cast<PropertyRNA *>(
922 BLI_findstring_ptr(&srna->cont.properties, identifier, offsetof(PropertyRNA, identifier)));
923}
924
926{
927 for (; srna; srna = srna->base) {
928 PropertyRNA *prop = RNA_struct_type_find_property_no_base(srna, identifier);
929 if (prop != nullptr) {
930 return prop;
931 }
932 }
933 return nullptr;
934}
935
936FunctionRNA *RNA_struct_find_function(StructRNA *srna, const char *identifier)
937{
938#if 1
939 FunctionRNA *func;
940 for (; srna; srna = srna->base) {
942 &srna->functions, identifier, offsetof(FunctionRNA, identifier));
943 if (func) {
944 return func;
945 }
946 }
947 return nullptr;
948
949 /* functional but slow */
950#else
951 PropertyRNA *iterprop;
952 FunctionRNA *func;
953
954 PointerRNA tptr = RNA_pointer_create(nullptr, &RNA_Struct, srna);
955 iterprop = RNA_struct_find_property(&tptr, "functions");
956
957 func = nullptr;
958
959 RNA_PROP_BEGIN (&tptr, funcptr, iterprop) {
960 if (STREQ(identifier, RNA_function_identifier(funcptr.data))) {
961 func = funcptr.data;
962 break;
963 }
964 }
966
967 return func;
968#endif
969}
970
972{
973 return &srna->functions;
974}
975
977{
978 return type->reg;
979}
980
982{
983 do {
984 if (type->unreg) {
985 return type->unreg;
986 }
987 } while ((type = type->base));
988
989 return nullptr;
990}
991
993{
994 StructRNA *type = ptr->type;
995
996 do {
997 if (type->instance) {
998 return type->instance(ptr);
999 }
1000 } while ((type = type->base));
1001
1002 return nullptr;
1003}
1004
1006{
1007 return srna->py_type;
1008}
1009
1010void RNA_struct_py_type_set(StructRNA *srna, void *py_type)
1011{
1012 srna->py_type = py_type;
1013}
1014
1016{
1017 return srna->blender_type;
1018}
1019
1020void RNA_struct_blender_type_set(StructRNA *srna, void *blender_type)
1021{
1022 srna->blender_type = blender_type;
1023}
1024
1025char *RNA_struct_name_get_alloc(PointerRNA *ptr, char *fixedbuf, int fixedlen, int *r_len)
1026{
1027 PropertyRNA *nameprop;
1028
1029 if (ptr->data && (nameprop = RNA_struct_name_property(ptr->type))) {
1030 return RNA_property_string_get_alloc(ptr, nameprop, fixedbuf, fixedlen, r_len);
1031 }
1032
1033 return nullptr;
1034}
1035
1036bool RNA_struct_available_or_report(ReportList *reports, const char *identifier)
1037{
1038 const StructRNA *srna_exists = RNA_struct_find(identifier);
1039 if (UNLIKELY(srna_exists != nullptr)) {
1040 /* Use comprehensive string construction since this is such a rare occurrence
1041 * and information here may cut down time troubleshooting. */
1042 DynStr *dynstr = BLI_dynstr_new();
1043 BLI_dynstr_appendf(dynstr, "Type identifier '%s' is already in use: '", identifier);
1044 BLI_dynstr_append(dynstr, srna_exists->identifier);
1045 int i = 0;
1046 if (srna_exists->base) {
1047 for (const StructRNA *base = srna_exists->base; base; base = base->base) {
1048 BLI_dynstr_append(dynstr, "(");
1049 BLI_dynstr_append(dynstr, base->identifier);
1050 i += 1;
1051 }
1052 while (i--) {
1053 BLI_dynstr_append(dynstr, ")");
1054 }
1055 }
1056 BLI_dynstr_append(dynstr, "'.");
1057 char *result = BLI_dynstr_get_cstring(dynstr);
1058 BLI_dynstr_free(dynstr);
1059 BKE_report(reports, RPT_ERROR, result);
1060 MEM_freeN(result);
1061 return false;
1062 }
1063 return true;
1064}
1065
1067 const char *identifier,
1068 const char *sep)
1069{
1070 const int len_sep = strlen(sep);
1071 const int len_id = strlen(identifier);
1072 const char *p = strstr(identifier, sep);
1073 /* TODO: make error, for now warning until add-ons update. */
1074#if 1
1075 const int report_level = RPT_WARNING;
1076 const bool failure = true;
1077#else
1078 const int report_level = RPT_ERROR;
1079 const bool failure = false;
1080#endif
1081 if (p == nullptr || p == identifier || p + len_sep >= identifier + len_id) {
1082 BKE_reportf(reports,
1083 eReportType(report_level),
1084 "'%s' does not contain '%s' with prefix and suffix",
1085 identifier,
1086 sep);
1087 return failure;
1088 }
1089
1090 const char *c, *start, *end, *last;
1091 start = identifier;
1092 end = p;
1093 last = end - 1;
1094 for (c = start; c != end; c++) {
1095 if (((*c >= 'A' && *c <= 'Z') || ((c != start) && (*c >= '0' && *c <= '9')) ||
1096 ((c != start) && (c != last) && (*c == '_'))) == 0)
1097 {
1098 BKE_reportf(reports,
1099 eReportType(report_level),
1100 "'%s' doesn't have upper case alpha-numeric prefix",
1101 identifier);
1102 return failure;
1103 }
1104 }
1105
1106 start = p + len_sep;
1107 end = identifier + len_id;
1108 last = end - 1;
1109 for (c = start; c != end; c++) {
1110 if (((*c >= 'A' && *c <= 'Z') || (*c >= 'a' && *c <= 'z') || (*c >= '0' && *c <= '9') ||
1111 ((c != start) && (c != last) && (*c == '_'))) == 0)
1112 {
1113 BKE_reportf(reports,
1114 eReportType(report_level),
1115 "'%s' doesn't have an alpha-numeric suffix",
1116 identifier);
1117 return failure;
1118 }
1119 }
1120 return true;
1121}
1122
1123/* Property Information */
1124
1125const char *RNA_property_identifier(const PropertyRNA *prop)
1126{
1127 return rna_ensure_property_identifier(prop);
1128}
1129
1131{
1133}
1134
1139
1141{
1142 PropertyRNA *rna_prop = rna_ensure_property(prop);
1143
1144 /* For custom properties, find and parse the 'subtype' metadata field. */
1145 if (prop->magic != RNA_MAGIC) {
1146 IDProperty *idprop = (IDProperty *)prop;
1147
1148 if (idprop->type == IDP_STRING && idprop->subtype == IDP_STRING_SUB_BYTE) {
1149 return PROP_BYTESTRING;
1150 }
1151
1152 if (idprop->ui_data) {
1153 IDPropertyUIData *ui_data = idprop->ui_data;
1154 return (PropertySubType)ui_data->rna_subtype;
1155 }
1156 }
1157
1158 return rna_prop->subtype;
1159}
1160
1165
1167{
1168 PropertyRNA *rna_prop = rna_ensure_property(prop);
1169
1170 switch (rna_prop->type) {
1171 case PROP_INT: {
1172 IntPropertyRNA *iprop = (IntPropertyRNA *)rna_prop;
1173 return iprop->ui_scale_type;
1174 }
1175 case PROP_FLOAT: {
1176 FloatPropertyRNA *fprop = (FloatPropertyRNA *)rna_prop;
1177 return fprop->ui_scale_type;
1178 }
1179 default:
1180 return PROP_SCALE_LINEAR;
1181 }
1182}
1183
1185{
1186 return rna_ensure_property(prop)->flag;
1187}
1188
1190{
1191 return rna_ensure_property(prop)->tags;
1192}
1193
1195{
1196 return (rna_ensure_property(prop)->flag_internal & PROP_INTERN_BUILTIN) != 0;
1197}
1198
1200{
1201 return prop->py_data;
1202}
1203
1208
1213
1215{
1216 PropertyRNA *rprop = rna_ensure_property(prop);
1217
1218 if (length) {
1220 }
1221
1222 return rprop->arraydimension;
1223}
1224
1226{
1228
1230
1231 return len[dim];
1232}
1233
1235{
1236 const char *vectoritem = "XYZW";
1237 const char *quatitem = "WXYZ";
1238 const char *coloritem = "RGBA";
1239 PropertySubType subtype = RNA_property_subtype(prop);
1240
1241 BLI_assert(index >= 0);
1242
1243 /* get string to use for array index */
1244 if ((index < 4) && ELEM(subtype, PROP_QUATERNION, PROP_AXISANGLE)) {
1245 return quatitem[index];
1246 }
1247 if ((index < 4) && ELEM(subtype,
1250 PROP_XYZ,
1252 PROP_EULER,
1255 PROP_COORDS))
1256 {
1257 return vectoritem[index];
1258 }
1259 if ((index < 4) && ELEM(subtype, PROP_COLOR, PROP_COLOR_GAMMA)) {
1260 return coloritem[index];
1261 }
1262
1263 return '\0';
1264}
1265
1267{
1268 /* Don't use custom property sub-types in RNA path lookup. */
1270
1271 /* get index based on string name/alias */
1272 /* maybe a function to find char index in string would be better than all the switches */
1273 if (ELEM(subtype, PROP_QUATERNION, PROP_AXISANGLE)) {
1274 switch (name) {
1275 case 'w':
1276 return 0;
1277 case 'x':
1278 return 1;
1279 case 'y':
1280 return 2;
1281 case 'z':
1282 return 3;
1283 }
1284 }
1285 else if (ELEM(subtype,
1288 PROP_XYZ,
1290 PROP_EULER,
1293 {
1294 switch (name) {
1295 case 'x':
1296 return 0;
1297 case 'y':
1298 return 1;
1299 case 'z':
1300 return 2;
1301 case 'w':
1302 return 3;
1303 }
1304 }
1305 else if (ELEM(subtype, PROP_COLOR, PROP_COLOR_GAMMA)) {
1306 switch (name) {
1307 case 'r':
1308 return 0;
1309 case 'g':
1310 return 1;
1311 case 'b':
1312 return 2;
1313 case 'a':
1314 return 3;
1315 }
1316 }
1317
1318 return -1;
1319}
1320
1321void RNA_property_int_range(PointerRNA *ptr, PropertyRNA *prop, int *hardmin, int *hardmax)
1322{
1324 int softmin, softmax;
1325
1326 if (prop->magic != RNA_MAGIC) {
1327 const IDProperty *idprop = (IDProperty *)prop;
1328 if (idprop->ui_data) {
1329 IDPropertyUIDataInt *ui_data = (IDPropertyUIDataInt *)idprop->ui_data;
1330 *hardmin = ui_data->min;
1331 *hardmax = ui_data->max;
1332 }
1333 else {
1334 *hardmin = INT_MIN;
1335 *hardmax = INT_MAX;
1336 }
1337 return;
1338 }
1339
1340 if (iprop->range) {
1341 *hardmin = INT_MIN;
1342 *hardmax = INT_MAX;
1343
1344 iprop->range(ptr, hardmin, hardmax, &softmin, &softmax);
1345 }
1346 else if (iprop->range_ex) {
1347 *hardmin = INT_MIN;
1348 *hardmax = INT_MAX;
1349
1350 iprop->range_ex(ptr, prop, hardmin, hardmax, &softmin, &softmax);
1351 }
1352 else {
1353 *hardmin = iprop->hardmin;
1354 *hardmax = iprop->hardmax;
1355 }
1356}
1357
1359 PointerRNA *ptr, PropertyRNA *prop, int *softmin, int *softmax, int *step)
1360{
1362 int hardmin, hardmax;
1363
1364 if (prop->magic != RNA_MAGIC) {
1365 const IDProperty *idprop = (IDProperty *)prop;
1366 if (idprop->ui_data) {
1367 IDPropertyUIDataInt *ui_data_int = (IDPropertyUIDataInt *)idprop->ui_data;
1368 *softmin = ui_data_int->soft_min;
1369 *softmax = ui_data_int->soft_max;
1370 *step = ui_data_int->step;
1371 }
1372 else {
1373 *softmin = INT_MIN;
1374 *softmax = INT_MAX;
1375 *step = 1;
1376 }
1377 return;
1378 }
1379
1380 *softmin = iprop->softmin;
1381 *softmax = iprop->softmax;
1382
1383 if (iprop->range) {
1384 hardmin = INT_MIN;
1385 hardmax = INT_MAX;
1386
1387 iprop->range(ptr, &hardmin, &hardmax, softmin, softmax);
1388
1389 *softmin = max_ii(*softmin, hardmin);
1390 *softmax = min_ii(*softmax, hardmax);
1391 }
1392 else if (iprop->range_ex) {
1393 hardmin = INT_MIN;
1394 hardmax = INT_MAX;
1395
1396 iprop->range_ex(ptr, prop, &hardmin, &hardmax, softmin, softmax);
1397
1398 *softmin = max_ii(*softmin, hardmin);
1399 *softmax = min_ii(*softmax, hardmax);
1400 }
1401
1402 *step = iprop->step;
1403}
1404
1405void RNA_property_float_range(PointerRNA *ptr, PropertyRNA *prop, float *hardmin, float *hardmax)
1406{
1408 float softmin, softmax;
1409
1410 if (prop->magic != RNA_MAGIC) {
1411 const IDProperty *idprop = (IDProperty *)prop;
1412 if (idprop->ui_data) {
1414 *hardmin = float(ui_data->min);
1415 *hardmax = float(ui_data->max);
1416 }
1417 else {
1418 *hardmin = -FLT_MAX;
1419 *hardmax = FLT_MAX;
1420 }
1421 return;
1422 }
1423
1424 if (fprop->range) {
1425 *hardmin = -FLT_MAX;
1426 *hardmax = FLT_MAX;
1427
1428 fprop->range(ptr, hardmin, hardmax, &softmin, &softmax);
1429 }
1430 else if (fprop->range_ex) {
1431 *hardmin = -FLT_MAX;
1432 *hardmax = FLT_MAX;
1433
1434 fprop->range_ex(ptr, prop, hardmin, hardmax, &softmin, &softmax);
1435 }
1436 else {
1437 *hardmin = fprop->hardmin;
1438 *hardmax = fprop->hardmax;
1439 }
1440}
1441
1443 PropertyRNA *prop,
1444 float *softmin,
1445 float *softmax,
1446 float *step,
1447 float *precision)
1448{
1450 float hardmin, hardmax;
1451
1452 if (prop->magic != RNA_MAGIC) {
1453 const IDProperty *idprop = (IDProperty *)prop;
1454 if (idprop->ui_data) {
1456 *softmin = float(ui_data->soft_min);
1457 *softmax = float(ui_data->soft_max);
1458 *step = ui_data->step;
1459 *precision = float(ui_data->precision);
1460 }
1461 else {
1462 *softmin = -FLT_MAX;
1463 *softmax = FLT_MAX;
1464 *step = 1.0f;
1465 *precision = 3.0f;
1466 }
1467 return;
1468 }
1469
1470 *softmin = fprop->softmin;
1471 *softmax = fprop->softmax;
1472
1473 if (fprop->range) {
1474 hardmin = -FLT_MAX;
1475 hardmax = FLT_MAX;
1476
1477 fprop->range(ptr, &hardmin, &hardmax, softmin, softmax);
1478
1479 *softmin = max_ff(*softmin, hardmin);
1480 *softmax = min_ff(*softmax, hardmax);
1481 }
1482 else if (fprop->range_ex) {
1483 hardmin = -FLT_MAX;
1484 hardmax = FLT_MAX;
1485
1486 fprop->range_ex(ptr, prop, &hardmin, &hardmax, softmin, softmax);
1487
1488 *softmin = max_ff(*softmin, hardmin);
1489 *softmax = min_ff(*softmax, hardmax);
1490 }
1491
1492 *step = fprop->step;
1493 *precision = float(fprop->precision);
1494}
1495
1497{
1498 float min, max;
1499
1500 RNA_property_float_range(ptr, prop, &min, &max);
1501
1502 if (*value < min) {
1503 *value = min;
1504 return -1;
1505 }
1506 if (*value > max) {
1507 *value = max;
1508 return 1;
1509 }
1510 return 0;
1511}
1512
1514{
1515 int min, max;
1516
1517 RNA_property_int_range(ptr, prop, &min, &max);
1518
1519 if (*value < min) {
1520 *value = min;
1521 return -1;
1522 }
1523 if (*value > max) {
1524 *value = max;
1525 return 1;
1526 }
1527 return 0;
1528}
1529
1531{
1533 return sprop->maxlength;
1534}
1535
1537{
1538 if (prop->magic != RNA_MAGIC) {
1539 const IDProperty *idprop = (IDProperty *)prop;
1540 if (idprop->type == IDP_ID) {
1541 const IDPropertyUIDataID *ui_data = (const IDPropertyUIDataID *)idprop->ui_data;
1542 if (ui_data) {
1543 return ID_code_to_RNA_type(ui_data->id_type);
1544 }
1545 }
1546 }
1547
1548 prop = rna_ensure_property(prop);
1549
1550 if (prop->type == PROP_POINTER) {
1551 PointerPropertyRNA *pprop = (PointerPropertyRNA *)prop;
1552
1553 if (pprop->type_fn) {
1554 return pprop->type_fn(ptr);
1555 }
1556 if (pprop->type) {
1557 return pprop->type;
1558 }
1559 }
1560 else if (prop->type == PROP_COLLECTION) {
1562
1563 if (cprop->item_type) {
1564 return cprop->item_type;
1565 }
1566 }
1567 /* ignore other types, rna_struct_find_nested calls with unchecked props */
1568
1569 return &RNA_UnknownType;
1570}
1571
1573{
1574 prop = rna_ensure_property(prop);
1575
1576 if (prop->type != PROP_POINTER) {
1577 printf("%s: %s is not a pointer property.\n", __func__, prop->identifier);
1578 return false;
1579 }
1580
1581 PointerPropertyRNA *pprop = (PointerPropertyRNA *)prop;
1582
1583 /* Can't point from linked to local datablock. */
1584 if (ptr->owner_id && value->owner_id && !BKE_id_can_use_id(*ptr->owner_id, *value->owner_id)) {
1585 return false;
1586 }
1587
1588 /* Check custom poll function. */
1589 if (!pprop->poll) {
1590 return true;
1591 }
1592
1593 if (rna_idproperty_check(&prop, ptr)) {
1594 return reinterpret_cast<PropPointerPollFuncPy>(reinterpret_cast<void *>(pprop->poll))(
1595 ptr, *value, prop);
1596 }
1597 return pprop->poll(ptr, *value);
1598}
1599
1601 PointerRNA *ptr,
1602 PropertyRNA *prop,
1603 const bool use_static,
1604 const EnumPropertyItem **r_item,
1605 int *r_totitem,
1606 bool *r_free)
1607{
1608 if (!use_static && prop->magic != RNA_MAGIC) {
1609 const IDProperty *idprop = (IDProperty *)prop;
1610 if (idprop->type == IDP_INT) {
1611 IDPropertyUIDataInt *ui_data = reinterpret_cast<IDPropertyUIDataInt *>(idprop->ui_data);
1612
1613 int totitem = 0;
1614 EnumPropertyItem *result = nullptr;
1615 if (ui_data) {
1616 for (const IDPropertyUIDataEnumItem &idprop_item :
1617 blender::Span(ui_data->enum_items, ui_data->enum_items_num))
1618 {
1619 BLI_assert(idprop_item.identifier != nullptr);
1620 BLI_assert(idprop_item.name != nullptr);
1621 const EnumPropertyItem item = {idprop_item.value,
1622 idprop_item.identifier,
1623 idprop_item.icon,
1624 idprop_item.name,
1625 idprop_item.description ? idprop_item.description : ""};
1626 RNA_enum_item_add(&result, &totitem, &item);
1627 }
1628 }
1629
1630 RNA_enum_item_end(&result, &totitem);
1631 *r_item = result;
1632 if (r_totitem) {
1633 /* Exclude the terminator item. */
1634 *r_totitem = totitem - 1;
1635 }
1636 *r_free = true;
1637 return;
1638 }
1639 }
1640
1642
1643 *r_free = false;
1644
1645 if (!use_static && (eprop->item_fn != nullptr)) {
1646 const bool no_context = (prop->flag & PROP_ENUM_NO_CONTEXT) ||
1648 (ptr->owner_id == nullptr));
1649 if (C != nullptr || no_context) {
1650 const EnumPropertyItem *item;
1651
1652 item = eprop->item_fn(no_context ? nullptr : C, ptr, prop, r_free);
1653
1654 /* any callbacks returning nullptr should be fixed */
1655 BLI_assert(item != nullptr);
1656
1657 if (r_totitem) {
1658 int tot;
1659 for (tot = 0; item[tot].identifier; tot++) {
1660 /* pass */
1661 }
1662 *r_totitem = tot;
1663 }
1664
1665 *r_item = item;
1666 return;
1667 }
1668 }
1669
1670 *r_item = eprop->item;
1671 if (r_totitem) {
1672 *r_totitem = eprop->totitem;
1673 }
1674}
1675
1677 PointerRNA *ptr,
1678 PropertyRNA *prop,
1679 const EnumPropertyItem **r_item,
1680 int *r_totitem,
1681 bool *r_free)
1682{
1683 RNA_property_enum_items_ex(C, ptr, prop, false, r_item, r_totitem, r_free);
1684}
1685
1686#ifdef WITH_INTERNATIONAL
1687static void property_enum_translate(PropertyRNA *prop,
1688 EnumPropertyItem **r_item,
1689 const int *totitem,
1690 bool *r_free)
1691{
1692 if (!(prop->flag & PROP_ENUM_NO_TRANSLATE)) {
1693 int i;
1694
1695 /* NOTE: Only do those tests once, and then use BLT_pgettext. */
1696 bool do_iface = BLT_translate_iface();
1697 bool do_tooltip = BLT_translate_tooltips();
1698 EnumPropertyItem *nitem;
1699
1700 if (!(do_iface || do_tooltip)) {
1701 return;
1702 }
1703
1704 if (*r_free) {
1705 nitem = *r_item;
1706 }
1707 else {
1708 const EnumPropertyItem *item = *r_item;
1709 int tot;
1710
1711 if (totitem) {
1712 tot = *totitem;
1713 }
1714 else {
1715 /* count */
1716 for (tot = 0; item[tot].identifier; tot++) {
1717 /* pass */
1718 }
1719 }
1720
1721 nitem = static_cast<EnumPropertyItem *>(
1722 MEM_mallocN(sizeof(EnumPropertyItem) * (tot + 1), __func__));
1723 memcpy(nitem, item, sizeof(EnumPropertyItem) * (tot + 1));
1724
1725 *r_free = true;
1726 }
1727
1728 for (i = 0; nitem[i].identifier; i++) {
1729 if (nitem[i].name && do_iface) {
1730 nitem[i].name = BLT_pgettext(prop->translation_context, nitem[i].name);
1731 }
1732 if (nitem[i].description && do_tooltip) {
1733 nitem[i].description = BLT_pgettext(nullptr, nitem[i].description);
1734 }
1735 }
1736
1737 *r_item = nitem;
1738 }
1739}
1740#endif
1741
1743 PointerRNA *ptr,
1744 PropertyRNA *prop,
1745 const EnumPropertyItem **r_item,
1746 int *r_totitem,
1747 bool *r_free)
1748{
1749 RNA_property_enum_items(C, ptr, prop, r_item, r_totitem, r_free);
1750
1751#ifdef WITH_INTERNATIONAL
1752 /* Normally dropping 'const' is _not_ ok, in this case it's only modified if we own the memory
1753 * so allow the exception (callers are creating new arrays in this case). */
1754 property_enum_translate(prop, (EnumPropertyItem **)r_item, r_totitem, r_free);
1755#endif
1756}
1757
1759 PointerRNA *ptr,
1760 PropertyRNA *prop,
1761 const EnumPropertyItem **r_item,
1762 int *r_totitem,
1763 bool *r_free)
1764{
1766 int mem_size = sizeof(EnumPropertyItem) * (eprop->totitem + 1);
1767 /* first return all items */
1768 EnumPropertyItem *item_array = static_cast<EnumPropertyItem *>(
1769 MEM_mallocN(mem_size, "enum_gettext_all"));
1770 *r_free = true;
1771 memcpy(item_array, eprop->item, mem_size);
1772
1773 if (r_totitem) {
1774 *r_totitem = eprop->totitem;
1775 }
1776
1777 if (eprop->item_fn != nullptr) {
1778 const bool no_context = (prop->flag & PROP_ENUM_NO_CONTEXT) ||
1780 (ptr->owner_id == nullptr));
1781 if (C != nullptr || no_context) {
1782 const EnumPropertyItem *item;
1783 int i;
1784 bool free = false;
1785
1786 item = eprop->item_fn(no_context ? nullptr : nullptr, ptr, prop, &free);
1787
1788 /* any callbacks returning nullptr should be fixed */
1789 BLI_assert(item != nullptr);
1790
1791 for (i = 0; i < eprop->totitem; i++) {
1792 bool exists = false;
1793 int i_fixed;
1794
1795 /* Items that do not exist on list are returned,
1796 * but have their names/identifiers null'ed out. */
1797 for (i_fixed = 0; item[i_fixed].identifier; i_fixed++) {
1798 if (STREQ(item[i_fixed].identifier, item_array[i].identifier)) {
1799 exists = true;
1800 break;
1801 }
1802 }
1803
1804 if (!exists) {
1805 item_array[i].name = nullptr;
1806 item_array[i].identifier = "";
1807 }
1808 }
1809
1810 if (free) {
1811 MEM_freeN((void *)item);
1812 }
1813 }
1814 }
1815
1816#ifdef WITH_INTERNATIONAL
1817 property_enum_translate(prop, &item_array, r_totitem, r_free);
1818#endif
1819 *r_item = item_array;
1820}
1821
1823 bContext *C, PointerRNA *ptr, PropertyRNA *prop, const char *identifier, int *r_value)
1824{
1825 const EnumPropertyItem *item;
1826 bool free;
1827 bool found;
1828
1829 RNA_property_enum_items(C, ptr, prop, &item, nullptr, &free);
1830
1831 if (item) {
1832 const int i = RNA_enum_from_identifier(item, identifier);
1833 if (i != -1) {
1834 *r_value = item[i].value;
1835 found = true;
1836 }
1837 else {
1838 found = false;
1839 }
1840
1841 if (free) {
1842 MEM_freeN((void *)item);
1843 }
1844 }
1845 else {
1846 found = false;
1847 }
1848 return found;
1849}
1850
1851bool RNA_enum_identifier(const EnumPropertyItem *item, const int value, const char **r_identifier)
1852{
1853 const int i = RNA_enum_from_value(item, value);
1854 if (i != -1) {
1855 *r_identifier = item[i].identifier;
1856 return true;
1857 }
1858 return false;
1859}
1860
1862 const int value,
1863 const char **r_identifier)
1864{
1865 int index = 0;
1866 for (; item->identifier; item++) {
1867 if (item->identifier[0] && item->value & value) {
1868 r_identifier[index++] = item->identifier;
1869 }
1870 }
1871 r_identifier[index] = nullptr;
1872 return index;
1873}
1874
1875bool RNA_enum_name(const EnumPropertyItem *item, const int value, const char **r_name)
1876{
1877 const int i = RNA_enum_from_value(item, value);
1878 if (i != -1) {
1879 *r_name = item[i].name;
1880 return true;
1881 }
1882 return false;
1883}
1884
1886 const int value,
1887 const char **r_description)
1888{
1889 const int i = RNA_enum_from_value(item, value);
1890 if (i != -1) {
1891 *r_description = item[i].description;
1892 return true;
1893 }
1894 return false;
1895}
1896
1897int RNA_enum_from_identifier(const EnumPropertyItem *item, const char *identifier)
1898{
1899 int i = 0;
1900 for (; item->identifier; item++, i++) {
1901 if (item->identifier[0] && STREQ(item->identifier, identifier)) {
1902 return i;
1903 }
1904 }
1905 return -1;
1906}
1907
1909 const char *identifier,
1910 int *r_value)
1911{
1912 const int i = RNA_enum_from_identifier(item, identifier);
1913 if (i == -1) {
1914 return false;
1915 }
1916 *r_value = item[i].value;
1917 return true;
1918}
1919
1920int RNA_enum_from_name(const EnumPropertyItem *item, const char *name)
1921{
1922 int i = 0;
1923 for (; item->identifier; item++, i++) {
1924 if (item->identifier[0] && STREQ(item->name, name)) {
1925 return i;
1926 }
1927 }
1928 return -1;
1929}
1930
1931int RNA_enum_from_value(const EnumPropertyItem *item, const int value)
1932{
1933 int i = 0;
1934 for (; item->identifier; item++, i++) {
1935 if (item->identifier[0] && item->value == value) {
1936 return i;
1937 }
1938 }
1939 return -1;
1940}
1941
1943{
1944 uint i = 0;
1945
1946 while (item->identifier) {
1947 item++;
1948 i++;
1949 }
1950
1951 return i;
1952}
1953
1955 bContext *C, PointerRNA *ptr, PropertyRNA *prop, const int value, const char **r_identifier)
1956{
1957 const EnumPropertyItem *item = nullptr;
1958 bool free;
1959
1960 RNA_property_enum_items(C, ptr, prop, &item, nullptr, &free);
1961 if (item) {
1962 bool result;
1963 result = RNA_enum_identifier(item, value, r_identifier);
1964 if (free) {
1965 MEM_freeN((void *)item);
1966 }
1967 return result;
1968 }
1969 return false;
1970}
1971
1973 bContext *C, PointerRNA *ptr, PropertyRNA *prop, const int value, const char **r_name)
1974{
1975 const EnumPropertyItem *item = nullptr;
1976 bool free;
1977
1978 RNA_property_enum_items(C, ptr, prop, &item, nullptr, &free);
1979 if (item) {
1980 bool result;
1981 result = RNA_enum_name(item, value, r_name);
1982 if (free) {
1983 MEM_freeN((void *)item);
1984 }
1985
1986 return result;
1987 }
1988 return false;
1989}
1990
1992 bContext *C, PointerRNA *ptr, PropertyRNA *prop, const int value, const char **r_name)
1993{
1994 bool result;
1995
1996 result = RNA_property_enum_name(C, ptr, prop, value, r_name);
1997
1998 if (result) {
1999 if (!(prop->flag & PROP_ENUM_NO_TRANSLATE)) {
2000 *r_name = BLT_translate_do_iface(prop->translation_context, *r_name);
2001 }
2002 }
2003
2004 return result;
2005}
2006
2008 bContext *C, PointerRNA *ptr, PropertyRNA *prop, const int value, EnumPropertyItem *r_item)
2009{
2010 const EnumPropertyItem *item = nullptr;
2011 bool free;
2012
2013 RNA_property_enum_items(C, ptr, prop, &item, nullptr, &free);
2014 if (item) {
2015 const int i = RNA_enum_from_value(item, value);
2016 bool result;
2017
2018 if (i != -1) {
2019 *r_item = item[i];
2020 result = true;
2021 }
2022 else {
2023 result = false;
2024 }
2025
2026 if (free) {
2027 MEM_freeN((void *)item);
2028 }
2029
2030 return result;
2031 }
2032 return false;
2033}
2034
2036 bContext *C, PointerRNA *ptr, PropertyRNA *prop, const int value, EnumPropertyItem *r_item)
2037{
2038 const bool result = RNA_property_enum_item_from_value(C, ptr, prop, value, r_item);
2039
2040 if (result && !(prop->flag & PROP_ENUM_NO_TRANSLATE)) {
2041 r_item->name = BLT_translate_do_iface(prop->translation_context, r_item->name);
2042 r_item->description = BLT_translate_do_tooltip(nullptr, r_item->description);
2043 }
2044
2045 return result;
2046}
2047
2049 bContext *C, PointerRNA *ptr, PropertyRNA *prop, const int value, const char **r_identifier)
2050{
2051 const EnumPropertyItem *item = nullptr;
2052 bool free;
2053
2054 RNA_property_enum_items(C, ptr, prop, &item, nullptr, &free);
2055 if (item) {
2056 int result;
2057 result = RNA_enum_bitflag_identifiers(item, value, r_identifier);
2058 if (free) {
2059 MEM_freeN((void *)item);
2060 }
2061
2062 return result;
2063 }
2064 return 0;
2065}
2066
2067const char *RNA_property_ui_name(const PropertyRNA *prop)
2068{
2070}
2071
2073{
2074 return rna_ensure_property_name(prop);
2075}
2076
2078{
2080}
2081
2083{
2085}
2086
2088{
2090}
2091
2093{
2094 return rna_ensure_property((PropertyRNA *)prop)->icon;
2095}
2096
2098 PropertyRNA *prop_orig,
2099 const int index,
2100 const char **r_info)
2101{
2102 ID *id = ptr->owner_id;
2103
2104 PropertyRNA *prop = rna_ensure_property(prop_orig);
2105
2106 const char *info = "";
2107 const int flag = (prop->itemeditable != nullptr && index >= 0) ?
2108 prop->itemeditable(ptr, index) :
2109 (prop->editable != nullptr ? prop->editable(ptr, &info) : prop->flag);
2110 if (r_info != nullptr) {
2111 *r_info = info;
2112 }
2113
2114 /* Early return if the property itself is not editable. */
2115 if ((flag & PROP_EDITABLE) == 0) {
2116 return false;
2117 }
2118 /* Only considered registerable properties "internal"
2119 * because regular properties may not be editable and still be displayed. */
2120 if (flag & PROP_REGISTER) {
2121 if (r_info != nullptr && (*r_info)[0] == '\0') {
2122 *r_info = N_("This property is for internal use only and can't be edited");
2123 }
2124 return false;
2125 }
2126
2127 /* If there is no owning ID, the property is editable at this point. */
2128 if (id == nullptr) {
2129 return true;
2130 }
2131
2132 /* Handle linked or liboverride ID cases. */
2133 const bool is_linked_prop_exception = (prop->flag & PROP_LIB_EXCEPTION) != 0;
2134 if (!ID_IS_EDITABLE(id)) {
2135 if (is_linked_prop_exception) {
2136 return true;
2137 }
2138 if (r_info != nullptr && (*r_info)[0] == '\0') {
2139 *r_info = N_("Can't edit this property from a linked data-block");
2140 }
2141 return false;
2142 }
2143 if (ID_IS_OVERRIDE_LIBRARY(id)) {
2144 const bool is_liboverride_system = BKE_lib_override_library_is_system_defined(G_MAIN, id);
2145 if (!RNA_property_overridable_get(ptr, prop_orig)) {
2146 if (r_info != nullptr && (*r_info)[0] == '\0') {
2147 *r_info = N_("Can't edit this property from an override data-block");
2148 }
2149 return false;
2150 }
2151 if (is_liboverride_system && !is_linked_prop_exception) {
2152 if (r_info != nullptr && (*r_info)[0] == '\0') {
2153 *r_info = N_("Can't edit this property from a system override data-block");
2154 }
2155 return false;
2156 }
2157 }
2158
2159 /* At this point, property is owned by a local ID and therefore fully editable. */
2160 return true;
2161}
2162
2164{
2165 return prop->flag_internal & PROP_INTERN_RUNTIME;
2166}
2167
2169{
2170 return rna_property_editable_do(ptr, prop, -1, nullptr);
2171}
2172
2173bool RNA_property_editable_info(const PointerRNA *ptr, PropertyRNA *prop, const char **r_info)
2174{
2175 return rna_property_editable_do(ptr, prop, -1, r_info);
2176}
2177
2179{
2180 int flag;
2181 const char *dummy_info;
2182
2183 prop = rna_ensure_property(prop);
2184 flag = prop->editable ? prop->editable(ptr, &dummy_info) : prop->flag;
2185 return (flag & PROP_EDITABLE) != 0;
2186}
2187
2188bool RNA_property_editable_index(const PointerRNA *ptr, PropertyRNA *prop, const int index)
2189{
2190 BLI_assert(index >= 0);
2191
2192 return rna_property_editable_do(ptr, prop, index, nullptr);
2193}
2194
2196{
2197 /* check that base ID-block can support animation data */
2199 return false;
2200 }
2201
2202 PropertyRNA *prop_ensured = rna_ensure_property(prop_orig);
2203
2204 if (!(prop_ensured->flag & PROP_ANIMATABLE)) {
2205 return false;
2206 }
2207
2208 return true;
2209}
2210
2212{
2213 /* check that base ID-block can support animation data */
2214 if (!RNA_property_animateable(ptr, prop_orig)) {
2215 return false;
2216 }
2217
2218 /* Linked or LibOverride Action IDs are not editable at the FCurve level. */
2219 if (ptr->owner_id) {
2221 if (anim_data && anim_data->action &&
2222 (!ID_IS_EDITABLE(anim_data->action) || ID_IS_OVERRIDE_LIBRARY(anim_data->action)))
2223 {
2224 return false;
2225 }
2226 }
2227
2228 return rna_property_editable_do(ptr, prop_orig, -1, nullptr);
2229}
2230
2232{
2233 if (!RNA_property_anim_editable(ptr, prop)) {
2234 return false;
2235 }
2236
2237 /* LibOverrides can only get drivers if their animdata (if any) was created for the local
2238 * liboverride, and there is none in the linked reference.
2239 *
2240 * See also #rna_AnimaData_override_apply. */
2243 nullptr, ptr->owner_id, nullptr, nullptr);
2244 AnimData *linked_reference_anim_data = BKE_animdata_from_id(liboverride->reference);
2245 if (linked_reference_anim_data) {
2246 return false;
2247 }
2248 }
2249
2250 return true;
2251}
2252
2254{
2255 int len = 1, index;
2256 bool driven, special;
2257
2258 if (!prop) {
2259 return false;
2260 }
2261
2262 if (RNA_property_array_check(prop)) {
2264 }
2265
2266 for (index = 0; index < len; index++) {
2267 if (BKE_fcurve_find_by_rna(ptr, prop, index, nullptr, nullptr, &driven, &special)) {
2268 return true;
2269 }
2270 }
2271
2272 return false;
2273}
2275{
2276 const std::optional<std::string> path = RNA_path_from_ID_to_property(ptr, prop);
2277 bool ret = false;
2278
2279 if (path) {
2280 PointerRNA r_ptr;
2281 PropertyRNA *r_prop;
2282
2284 if (RNA_path_resolve(&id_ptr, path->c_str(), &r_ptr, &r_prop) == true) {
2285 ret = (prop == r_prop);
2286 }
2287 }
2288
2289 return ret;
2290}
2291
2293 bContext *C, Main *bmain, Scene *scene, PointerRNA *ptr, PropertyRNA *prop)
2294{
2295 const bool is_rna = (prop->magic == RNA_MAGIC);
2296 prop = rna_ensure_property(prop);
2297
2298 if (is_rna) {
2299 if (prop->update) {
2300 /* ideally no context would be needed for update, but there's some
2301 * parts of the code that need it still, so we have this exception */
2302 if (prop->flag & PROP_CONTEXT_UPDATE) {
2303 if (C) {
2305 ((ContextPropUpdateFunc)prop->update)(C, ptr, prop);
2306 }
2307 else {
2308 reinterpret_cast<ContextUpdateFunc>(reinterpret_cast<void *>(prop->update))(C, ptr);
2309 }
2310 }
2311 }
2312 else {
2313 prop->update(bmain, scene, ptr);
2314 }
2315 }
2316
2317#if 1
2318 /* TODO(@ideasman42): Should eventually be replaced entirely by message bus (below)
2319 * for now keep since copy-on-eval, bugs are hard to track when we have other missing updates.
2320 */
2321 if (prop->noteflag) {
2323 }
2324#endif
2325
2326 /* if C is nullptr, we're updating from animation.
2327 * avoid slow-down from f-curves by not publishing (for now). */
2328 if (C != nullptr) {
2329 wmMsgBus *mbus = CTX_wm_message_bus(C);
2330 /* we could add nullptr check, for now don't */
2331 WM_msg_publish_rna(mbus, ptr, prop);
2332 }
2333 if (ptr->owner_id != nullptr && ((prop->flag & PROP_NO_DEG_UPDATE) == 0)) {
2334 const short id_type = GS(ptr->owner_id->name);
2335 if (ID_TYPE_USE_COPY_ON_EVAL(id_type)) {
2336 if (prop->flag & PROP_DEG_SYNC_ONLY) {
2338 }
2339 else {
2341 }
2342 }
2343 }
2344 /* End message bus. */
2345 }
2346
2347 if (!is_rna || (prop->flag & PROP_IDPROPERTY)) {
2348
2349 /* Disclaimer: this logic is not applied consistently, causing some confusing behavior.
2350 *
2351 * - When animated (which skips update functions).
2352 * - When ID-properties are edited via Python (since RNA properties aren't used in this case).
2353 *
2354 * Adding updates will add a lot of overhead in the case of animation.
2355 * For Python it may cause unexpected slow-downs for developers using ID-properties
2356 * for data storage. Further, the root ID isn't available with nested data-structures.
2357 *
2358 * So editing custom properties only causes updates in the UI,
2359 * keep this exception because it happens to be useful for driving settings.
2360 * Python developers on the other hand will need to manually 'update_tag', see: #74000. */
2363
2364 /* When updating an ID pointer property, tag depsgraph for update. */
2367 }
2368
2370 if (ptr->owner_id) {
2372 }
2373 /* Not nice as well, but the only way to make sure material preview
2374 * is updated with custom nodes.
2375 */
2376 if ((prop->flag & PROP_IDPROPERTY) != 0 && (ptr->owner_id != nullptr) &&
2377 (GS(ptr->owner_id->name) == ID_NT))
2378 {
2380 }
2381 }
2382}
2383
2385{
2386 /* NOTE: must keep in sync with #rna_property_update. */
2387 return (prop->magic != RNA_MAGIC || prop->update || prop->noteflag);
2388}
2389
2394
2396{
2397 BLI_assert(bmain != nullptr);
2398 rna_property_update(nullptr, bmain, scene, ptr, prop);
2399}
2400
2401/* ---------------------------------------------------------------------- */
2402
2403/* Property Data */
2404
2406{
2407 BoolPropertyRNA *bprop = (BoolPropertyRNA *)prop;
2408 IDProperty *idprop;
2409 bool value;
2410
2412 BLI_assert(RNA_property_array_check(prop) == false);
2413
2414 if ((idprop = rna_idproperty_check(&prop, ptr))) {
2415 value = IDP_Bool(idprop);
2416 }
2417 else if (bprop->get) {
2418 value = bprop->get(ptr);
2419 }
2420 else if (bprop->get_ex) {
2421 value = bprop->get_ex(ptr, prop);
2422 }
2423 else {
2424 value = bprop->defaultvalue;
2425 }
2426
2427 BLI_assert(ELEM(value, false, true));
2428
2429 return value;
2430}
2431
2437#define USE_INT_IDPROPS_FOR_BOOLEAN_RNA_PROP
2438
2440{
2441 BoolPropertyRNA *bprop = (BoolPropertyRNA *)prop;
2442 IDProperty *idprop;
2443
2445 BLI_assert(RNA_property_array_check(prop) == false);
2446 BLI_assert(ELEM(value, false, true));
2447
2448 /* just in case other values are passed */
2449 BLI_assert(ELEM(value, true, false));
2450
2451 if ((idprop = rna_idproperty_check(&prop, ptr))) {
2452 IDP_Bool(idprop) = value;
2453 rna_idproperty_touch(idprop);
2454 }
2455 else if (bprop->set) {
2456 bprop->set(ptr, value);
2457 }
2458 else if (bprop->set_ex) {
2459 bprop->set_ex(ptr, prop, value);
2460 }
2461 else if (prop->flag & PROP_EDITABLE) {
2462 if (IDProperty *group = RNA_struct_idprops(ptr, true)) {
2463#ifdef USE_INT_IDPROPS_FOR_BOOLEAN_RNA_PROP
2465 group,
2467 .release());
2468#else
2470 group,
2472 .release());
2473#endif
2474 }
2475 }
2476}
2477
2479 const bool *defarr, int defarr_length, bool defvalue, int out_length, bool *r_values)
2480{
2481 if (defarr && defarr_length > 0) {
2482 defarr_length = std::min(defarr_length, out_length);
2483 memcpy(r_values, defarr, sizeof(bool) * defarr_length);
2484 }
2485 else {
2486 defarr_length = 0;
2487 }
2488
2489 for (int i = defarr_length; i < out_length; i++) {
2490 r_values[i] = defvalue;
2491 }
2492}
2493
2495 const int *defarr, int defarr_length, bool defvalue, int out_length, bool *r_values)
2496{
2497 if (defarr && defarr_length > 0) {
2498 defarr_length = std::min(defarr_length, out_length);
2499 for (int i = 0; i < defarr_length; i++) {
2500 r_values[i] = defarr[i] != 0;
2501 }
2502 }
2503 else {
2504 defarr_length = 0;
2505 }
2506
2507 for (int i = defarr_length; i < out_length; i++) {
2508 r_values[i] = defvalue;
2509 }
2510}
2511
2513 BoolPropertyRNA *bprop,
2514 bool *r_values)
2515{
2516 if (ptr->data && bprop->get_default_array) {
2517 bprop->get_default_array(ptr, &bprop->property, r_values);
2518 return;
2519 }
2520
2521 int length = bprop->property.totarraylength;
2522 int out_length = RNA_property_array_length(ptr, (PropertyRNA *)bprop);
2523
2525 bprop->defaultarray, length, bprop->defaultvalue, out_length, r_values);
2526}
2527
2529{
2530 BoolPropertyRNA *bprop = (BoolPropertyRNA *)prop;
2531 IDProperty *idprop;
2532
2534 BLI_assert(RNA_property_array_check(prop) != false);
2535
2536 if ((idprop = rna_idproperty_check(&prop, ptr))) {
2537 if (prop->arraydimension == 0) {
2538 values[0] = RNA_property_boolean_get(ptr, prop);
2539 }
2540 else if (idprop->subtype == IDP_INT) {
2541 /* Some boolean IDProperty arrays might be saved in files as an integer
2542 * array property, since the boolean IDProperty type was added later. */
2543 int *values_src = static_cast<int *>(IDP_Array(idprop));
2544 for (uint i = 0; i < idprop->len; i++) {
2545 values[i] = bool(values_src[i]);
2546 }
2547 }
2548 else if (idprop->subtype == IDP_BOOLEAN) {
2549 bool *values_src = static_cast<bool *>(IDP_Array(idprop));
2550 for (int i = 0; i < idprop->len; i++) {
2551 values[i] = values_src[i];
2552 }
2553 }
2554 }
2555 else if (prop->arraydimension == 0) {
2556 values[0] = RNA_property_boolean_get(ptr, prop);
2557 }
2558 else if (bprop->getarray) {
2559 bprop->getarray(ptr, values);
2560 }
2561 else if (bprop->getarray_ex) {
2562 bprop->getarray_ex(ptr, prop, values);
2563 }
2564 else {
2566 }
2567}
2568
2570{
2571 bool tmp[RNA_MAX_ARRAY_LENGTH];
2573 bool value;
2574
2576 BLI_assert(RNA_property_array_check(prop) != false);
2577 BLI_assert(index >= 0);
2578 BLI_assert(index < len);
2579
2580 if (len <= RNA_MAX_ARRAY_LENGTH) {
2582 value = tmp[index];
2583 }
2584 else {
2585 bool *tmparray;
2586
2587 tmparray = static_cast<bool *>(MEM_mallocN(sizeof(bool) * len, __func__));
2588 RNA_property_boolean_get_array(ptr, prop, tmparray);
2589 value = tmparray[index];
2590 MEM_freeN(tmparray);
2591 }
2592
2593 BLI_assert(ELEM(value, false, true));
2594
2595 return value;
2596}
2597
2599{
2600 BoolPropertyRNA *bprop = (BoolPropertyRNA *)prop;
2601 IDProperty *idprop;
2602
2604 BLI_assert(RNA_property_array_check(prop) != false);
2605
2606 if ((idprop = rna_idproperty_check(&prop, ptr))) {
2607 if (prop->arraydimension == 0) {
2608 IDP_Int(idprop) = values[0];
2609 }
2610 else {
2611 BLI_assert(idprop->type = IDP_ARRAY);
2612 if (idprop->subtype == IDP_BOOLEAN) {
2613 memcpy(IDP_Array(idprop), values, sizeof(int8_t) * idprop->len);
2614 }
2615 else if (idprop->subtype == IDP_INT) {
2616 /* Support writing to integer and boolean IDProperties, since boolean
2617 * RNA properties used to be stored with integer IDProperties. */
2618 int *values_dst = static_cast<int *>(IDP_Array(idprop));
2619 for (uint i = 0; i < idprop->len; i++) {
2620 values_dst[i] = int(values[i]);
2621 }
2622 }
2623 }
2624 rna_idproperty_touch(idprop);
2625 }
2626 else if (prop->arraydimension == 0) {
2627 RNA_property_boolean_set(ptr, prop, values[0]);
2628 }
2629 else if (bprop->setarray) {
2630 bprop->setarray(ptr, values);
2631 }
2632 else if (bprop->setarray_ex) {
2633 bprop->setarray_ex(ptr, prop, values);
2634 }
2635 else if (prop->flag & PROP_EDITABLE) {
2636 IDPropertyTemplate val = {0};
2637
2638 val.array.len = prop->totarraylength;
2639#ifdef USE_INT_IDPROPS_FOR_BOOLEAN_RNA_PROP
2640 val.array.type = IDP_INT;
2641#else
2642 val.array.type = IDP_BOOLEAN;
2643#endif
2644
2645 if (IDProperty *group = RNA_struct_idprops(ptr, true)) {
2646 idprop = IDP_New(IDP_ARRAY, &val, prop->identifier, IDP_FLAG_STATIC_TYPE);
2647 IDP_AddToGroup(group, idprop);
2648 int *values_dst = static_cast<int *>(IDP_Array(idprop));
2649 for (uint i = 0; i < idprop->len; i++) {
2650 values_dst[i] = values[i];
2651 }
2652 }
2653 }
2654}
2655
2656void RNA_property_boolean_set_index(PointerRNA *ptr, PropertyRNA *prop, int index, bool value)
2657{
2658 bool tmp[RNA_MAX_ARRAY_LENGTH];
2660
2662 BLI_assert(RNA_property_array_check(prop) != false);
2663 BLI_assert(index >= 0);
2664 BLI_assert(index < len);
2665 BLI_assert(ELEM(value, false, true));
2666
2667 if (len <= RNA_MAX_ARRAY_LENGTH) {
2669 tmp[index] = value;
2671 }
2672 else {
2673 bool *tmparray;
2674
2675 tmparray = static_cast<bool *>(MEM_mallocN(sizeof(bool) * len, __func__));
2676 RNA_property_boolean_get_array(ptr, prop, tmparray);
2677 tmparray[index] = value;
2678 RNA_property_boolean_set_array(ptr, prop, tmparray);
2679 MEM_freeN(tmparray);
2680 }
2681}
2682
2684{
2685 /* TODO: Make defaults work for IDProperties. */
2687
2689 BLI_assert(RNA_property_array_check(prop) == false);
2690 BLI_assert(ELEM(bprop->defaultvalue, false, true));
2691
2692 if (prop->magic != RNA_MAGIC) {
2693 const IDProperty *idprop = (const IDProperty *)prop;
2694 if (idprop->ui_data) {
2695 switch (IDP_ui_data_type(idprop)) {
2697 const IDPropertyUIDataBool *ui_data = (const IDPropertyUIDataBool *)idprop->ui_data;
2698 return ui_data->default_value;
2699 }
2700 case IDP_UI_DATA_TYPE_INT: {
2701 const IDPropertyUIDataInt *ui_data = (const IDPropertyUIDataInt *)idprop->ui_data;
2702 return ui_data->default_value != 0;
2703 }
2704 default:
2706 }
2707 }
2708 return false;
2709 }
2710 if (bprop->get_default) {
2711 return bprop->get_default(ptr, prop);
2712 }
2713
2714 return bprop->defaultvalue;
2715}
2716
2718{
2720
2722 BLI_assert(RNA_property_array_check(prop) != false);
2723
2724 if (prop->magic != RNA_MAGIC) {
2725 const IDProperty *idprop = (const IDProperty *)prop;
2726 if (idprop->ui_data) {
2727 BLI_assert(idprop->type == IDP_ARRAY);
2728 switch (IDP_ui_data_type(idprop)) {
2730 const IDPropertyUIDataBool *ui_data = (const IDPropertyUIDataBool *)idprop->ui_data;
2731 if (ui_data->default_array) {
2733 ui_data->default_array_len,
2734 ui_data->default_value,
2735 idprop->len,
2736 values);
2737 }
2738 else {
2740 nullptr, 0, ui_data->default_value, idprop->len, values);
2741 }
2742 break;
2743 }
2744 case IDP_UI_DATA_TYPE_INT: {
2745 const IDPropertyUIDataInt *ui_data = (const IDPropertyUIDataInt *)idprop->ui_data;
2746 if (ui_data->default_array) {
2748 ui_data->default_array_len,
2749 ui_data->default_value,
2750 idprop->len,
2751 values);
2752 }
2753 else {
2755 nullptr, 0, ui_data->default_value, idprop->len, values);
2756 }
2757 break;
2758 }
2759 default:
2761 break;
2762 }
2763 }
2764 }
2765 else if (prop->arraydimension == 0) {
2766 values[0] = bprop->defaultvalue;
2767 }
2768 else {
2770 }
2771}
2772
2774{
2775 bool tmp[RNA_MAX_ARRAY_LENGTH];
2777
2779 BLI_assert(RNA_property_array_check(prop) != false);
2780 BLI_assert(index >= 0);
2781 BLI_assert(index < len);
2782
2783 if (len <= RNA_MAX_ARRAY_LENGTH) {
2785 return tmp[index];
2786 }
2787 bool *tmparray, value;
2788
2789 tmparray = static_cast<bool *>(MEM_mallocN(sizeof(bool) * len, __func__));
2791 value = tmparray[index];
2792 MEM_freeN(tmparray);
2793
2794 return value;
2795}
2796
2798{
2799 IntPropertyRNA *iprop = (IntPropertyRNA *)prop;
2800 IDProperty *idprop;
2801
2803 BLI_assert(RNA_property_array_check(prop) == false);
2804
2805 if ((idprop = rna_idproperty_check(&prop, ptr))) {
2806 return IDP_Int(idprop);
2807 }
2808 if (iprop->get) {
2809 return iprop->get(ptr);
2810 }
2811 if (iprop->get_ex) {
2812 return iprop->get_ex(ptr, prop);
2813 }
2814 return iprop->defaultvalue;
2815}
2816
2818{
2819 IntPropertyRNA *iprop = (IntPropertyRNA *)prop;
2820 IDProperty *idprop;
2821
2823 BLI_assert(RNA_property_array_check(prop) == false);
2824 /* useful to check on bad values but set function should clamp */
2825 // BLI_assert(RNA_property_int_clamp(ptr, prop, &value) == 0);
2826
2827 if ((idprop = rna_idproperty_check(&prop, ptr))) {
2828 RNA_property_int_clamp(ptr, prop, &value);
2829 IDP_Int(idprop) = value;
2830 rna_idproperty_touch(idprop);
2831 }
2832 else if (iprop->set) {
2833 iprop->set(ptr, value);
2834 }
2835 else if (iprop->set_ex) {
2836 iprop->set_ex(ptr, prop, value);
2837 }
2838 else if (prop->flag & PROP_EDITABLE) {
2839 RNA_property_int_clamp(ptr, prop, &value);
2840 if (IDProperty *group = RNA_struct_idprops(ptr, true)) {
2842 group,
2844 }
2845 }
2846}
2847
2849 const int *defarr, int defarr_length, int defvalue, int out_length, int *r_values)
2850{
2851 if (defarr && defarr_length > 0) {
2852 defarr_length = std::min(defarr_length, out_length);
2853 memcpy(r_values, defarr, sizeof(int) * defarr_length);
2854 }
2855 else {
2856 defarr_length = 0;
2857 }
2858
2859 for (int i = defarr_length; i < out_length; i++) {
2860 r_values[i] = defvalue;
2861 }
2862}
2863
2865 IntPropertyRNA *iprop,
2866 int *r_values)
2867{
2868 if (ptr->data && iprop->get_default_array) {
2869 iprop->get_default_array(ptr, &iprop->property, r_values);
2870 return;
2871 }
2872
2873 int length = iprop->property.totarraylength;
2874 int out_length = RNA_property_array_length(ptr, (PropertyRNA *)iprop);
2875
2877 iprop->defaultarray, length, iprop->defaultvalue, out_length, r_values);
2878}
2879
2881{
2882 IntPropertyRNA *iprop = (IntPropertyRNA *)prop;
2883 IDProperty *idprop;
2884
2886 BLI_assert(RNA_property_array_check(prop) != false);
2887
2888 if ((idprop = rna_idproperty_check(&prop, ptr))) {
2889 BLI_assert(idprop->len == RNA_property_array_length(ptr, prop) ||
2890 (prop->flag & PROP_IDPROPERTY));
2891 if (prop->arraydimension == 0) {
2892 values[0] = RNA_property_int_get(ptr, prop);
2893 }
2894 else {
2895 memcpy(values, IDP_Array(idprop), sizeof(int) * idprop->len);
2896 }
2897 }
2898 else if (prop->arraydimension == 0) {
2899 values[0] = RNA_property_int_get(ptr, prop);
2900 }
2901 else if (iprop->getarray) {
2902 iprop->getarray(ptr, values);
2903 }
2904 else if (iprop->getarray_ex) {
2905 iprop->getarray_ex(ptr, prop, values);
2906 }
2907 else {
2909 }
2910}
2911
2913{
2914 const int array_len = RNA_property_array_length(ptr, prop);
2915
2916 if (array_len <= 0) {
2917 values[0] = 0;
2918 values[1] = 0;
2919 }
2920 else if (array_len == 1) {
2921 RNA_property_int_get_array(ptr, prop, values);
2922 values[1] = values[0];
2923 }
2924 else {
2925 int arr_stack[32];
2926 int *arr;
2927 int i;
2928
2929 if (array_len > 32) {
2930 arr = static_cast<int *>(MEM_mallocN(sizeof(int) * array_len, __func__));
2931 }
2932 else {
2933 arr = arr_stack;
2934 }
2935
2936 RNA_property_int_get_array(ptr, prop, arr);
2937 values[0] = values[1] = arr[0];
2938 for (i = 1; i < array_len; i++) {
2939 values[0] = std::min(values[0], arr[i]);
2940 values[1] = std::max(values[1], arr[i]);
2941 }
2942
2943 if (arr != arr_stack) {
2944 MEM_freeN(arr);
2945 }
2946 }
2947}
2948
2950{
2951 int tmp[RNA_MAX_ARRAY_LENGTH];
2953
2955 BLI_assert(RNA_property_array_check(prop) != false);
2956 BLI_assert(index >= 0);
2957 BLI_assert(index < len);
2958
2959 if (len <= RNA_MAX_ARRAY_LENGTH) {
2960 RNA_property_int_get_array(ptr, prop, tmp);
2961 return tmp[index];
2962 }
2963 int *tmparray, value;
2964
2965 tmparray = static_cast<int *>(MEM_mallocN(sizeof(int) * len, __func__));
2966 RNA_property_int_get_array(ptr, prop, tmparray);
2967 value = tmparray[index];
2968 MEM_freeN(tmparray);
2969
2970 return value;
2971}
2972
2974{
2975 using namespace blender;
2976 IntPropertyRNA *iprop = (IntPropertyRNA *)prop;
2977 IDProperty *idprop;
2978
2980 BLI_assert(RNA_property_array_check(prop) != false);
2981
2982 if ((idprop = rna_idproperty_check(&prop, ptr))) {
2983 BLI_assert(idprop->len == RNA_property_array_length(ptr, prop) ||
2984 (prop->flag & PROP_IDPROPERTY));
2985 if (prop->arraydimension == 0) {
2986 IDP_Int(idprop) = values[0];
2987 }
2988 else {
2989 memcpy(IDP_Array(idprop), values, sizeof(int) * idprop->len);
2990 }
2991
2992 rna_idproperty_touch(idprop);
2993 }
2994 else if (prop->arraydimension == 0) {
2995 RNA_property_int_set(ptr, prop, values[0]);
2996 }
2997 else if (iprop->setarray) {
2998 iprop->setarray(ptr, values);
2999 }
3000 else if (iprop->setarray_ex) {
3001 iprop->setarray_ex(ptr, prop, values);
3002 }
3003 else if (prop->flag & PROP_EDITABLE) {
3004 // RNA_property_int_clamp_array(ptr, prop, &value); /* TODO. */
3005 if (IDProperty *group = RNA_struct_idprops(ptr, true)) {
3006 IDP_AddToGroup(group,
3007 bke::idprop::create(prop->identifier,
3008 Span(values, prop->totarraylength),
3010 .release());
3011 }
3012 }
3013}
3014
3015void RNA_property_int_set_index(PointerRNA *ptr, PropertyRNA *prop, int index, int value)
3016{
3017 int tmp[RNA_MAX_ARRAY_LENGTH];
3019
3021 BLI_assert(RNA_property_array_check(prop) != false);
3022 BLI_assert(index >= 0);
3023 BLI_assert(index < len);
3024
3025 if (len <= RNA_MAX_ARRAY_LENGTH) {
3026 RNA_property_int_get_array(ptr, prop, tmp);
3027 tmp[index] = value;
3028 RNA_property_int_set_array(ptr, prop, tmp);
3029 }
3030 else {
3031 int *tmparray;
3032
3033 tmparray = static_cast<int *>(MEM_mallocN(sizeof(int) * len, __func__));
3034 RNA_property_int_get_array(ptr, prop, tmparray);
3035 tmparray[index] = value;
3036 RNA_property_int_set_array(ptr, prop, tmparray);
3037 MEM_freeN(tmparray);
3038 }
3039}
3040
3042{
3044
3045 if (prop->magic != RNA_MAGIC) {
3046 const IDProperty *idprop = (const IDProperty *)prop;
3047 if (idprop->ui_data) {
3048 const IDPropertyUIDataInt *ui_data = (const IDPropertyUIDataInt *)idprop->ui_data;
3049 return ui_data->default_value;
3050 }
3051 }
3052 if (iprop->get_default) {
3053 return iprop->get_default(ptr, prop);
3054 }
3055
3056 return iprop->defaultvalue;
3057}
3058
3060{
3061 if (prop->magic == RNA_MAGIC) {
3062 return false;
3063 }
3064
3065 IDProperty *idprop = (IDProperty *)prop;
3066 BLI_assert(idprop->type == IDP_INT);
3067
3069 ui_data->default_value = value;
3070 return true;
3071}
3072
3074{
3076
3078 BLI_assert(RNA_property_array_check(prop) != false);
3079
3080 if (prop->magic != RNA_MAGIC) {
3081 int length = rna_ensure_property_array_length(ptr, prop);
3082
3083 const IDProperty *idprop = (const IDProperty *)prop;
3084 if (idprop->ui_data) {
3085 BLI_assert(idprop->type == IDP_ARRAY);
3086 BLI_assert(idprop->subtype == IDP_INT);
3087 const IDPropertyUIDataInt *ui_data = (const IDPropertyUIDataInt *)idprop->ui_data;
3088 if (ui_data->default_array) {
3090 ui_data->default_array_len,
3091 ui_data->default_value,
3092 length,
3093 values);
3094 }
3095 else {
3097 nullptr, 0, ui_data->default_value, length, values);
3098 }
3099 }
3100 }
3101 else if (prop->arraydimension == 0) {
3102 values[0] = iprop->defaultvalue;
3103 }
3104 else {
3106 }
3107}
3108
3110{
3111 int tmp[RNA_MAX_ARRAY_LENGTH];
3113
3115 BLI_assert(RNA_property_array_check(prop) != false);
3116 BLI_assert(index >= 0);
3117 BLI_assert(index < len);
3118
3119 if (len <= RNA_MAX_ARRAY_LENGTH) {
3121 return tmp[index];
3122 }
3123 int *tmparray, value;
3124
3125 tmparray = static_cast<int *>(MEM_mallocN(sizeof(int) * len, __func__));
3126 RNA_property_int_get_default_array(ptr, prop, tmparray);
3127 value = tmparray[index];
3128 MEM_freeN(tmparray);
3129
3130 return value;
3131}
3132
3134{
3135 FloatPropertyRNA *fprop = (FloatPropertyRNA *)prop;
3136 IDProperty *idprop;
3137
3139 BLI_assert(RNA_property_array_check(prop) == false);
3140
3141 if ((idprop = rna_idproperty_check(&prop, ptr))) {
3142 if (idprop->type == IDP_FLOAT) {
3143 return IDP_Float(idprop);
3144 }
3145 return float(IDP_Double(idprop));
3146 }
3147 if (fprop->get) {
3148 return fprop->get(ptr);
3149 }
3150 if (fprop->get_ex) {
3151 return fprop->get_ex(ptr, prop);
3152 }
3153 return fprop->defaultvalue;
3154}
3155
3157{
3158 FloatPropertyRNA *fprop = (FloatPropertyRNA *)prop;
3159 IDProperty *idprop;
3160
3162 BLI_assert(RNA_property_array_check(prop) == false);
3163 /* useful to check on bad values but set function should clamp */
3164 // BLI_assert(RNA_property_float_clamp(ptr, prop, &value) == 0);
3165
3166 if ((idprop = rna_idproperty_check(&prop, ptr))) {
3167 RNA_property_float_clamp(ptr, prop, &value);
3168 if (idprop->type == IDP_FLOAT) {
3169 IDP_Float(idprop) = value;
3170 }
3171 else {
3172 IDP_Double(idprop) = value;
3173 }
3174
3175 rna_idproperty_touch(idprop);
3176 }
3177 else if (fprop->set) {
3178 fprop->set(ptr, value);
3179 }
3180 else if (fprop->set_ex) {
3181 fprop->set_ex(ptr, prop, value);
3182 }
3183 else if (prop->flag & PROP_EDITABLE) {
3184 RNA_property_float_clamp(ptr, prop, &value);
3185 if (IDProperty *group = RNA_struct_idprops(ptr, true)) {
3187 group,
3189 }
3190 }
3191}
3192
3194 const float *defarr, int defarr_length, float defvalue, int out_length, float *r_values)
3195{
3196 if (defarr && defarr_length > 0) {
3197 defarr_length = std::min(defarr_length, out_length);
3198 memcpy(r_values, defarr, sizeof(float) * defarr_length);
3199 }
3200 else {
3201 defarr_length = 0;
3202 }
3203
3204 for (int i = defarr_length; i < out_length; i++) {
3205 r_values[i] = defvalue;
3206 }
3207}
3208
3212static void rna_property_float_fill_default_array_values_double(const double *default_array,
3213 const int default_array_len,
3214 const double default_value,
3215 const int out_length,
3216 float *r_values)
3217{
3218 const int array_copy_len = std::min(out_length, default_array_len);
3219
3220 for (int i = 0; i < array_copy_len; i++) {
3221 r_values[i] = float(default_array[i]);
3222 }
3223
3224 for (int i = array_copy_len; i < out_length; i++) {
3225 r_values[i] = float(default_value);
3226 }
3227}
3228
3230 FloatPropertyRNA *fprop,
3231 float *r_values)
3232{
3233 if (ptr->data && fprop->get_default_array) {
3234 fprop->get_default_array(ptr, &fprop->property, r_values);
3235 return;
3236 }
3237
3238 int length = fprop->property.totarraylength;
3239 int out_length = RNA_property_array_length(ptr, (PropertyRNA *)fprop);
3240
3242 fprop->defaultarray, length, fprop->defaultvalue, out_length, r_values);
3243}
3244
3246{
3247 FloatPropertyRNA *fprop = (FloatPropertyRNA *)prop;
3248 IDProperty *idprop;
3249 int i;
3250
3252 BLI_assert(RNA_property_array_check(prop) != false);
3253
3254 if ((idprop = rna_idproperty_check(&prop, ptr))) {
3255 BLI_assert(idprop->len == RNA_property_array_length(ptr, prop) ||
3256 (prop->flag & PROP_IDPROPERTY));
3257 if (prop->arraydimension == 0) {
3258 values[0] = RNA_property_float_get(ptr, prop);
3259 }
3260 else if (idprop->subtype == IDP_FLOAT) {
3261 memcpy(values, IDP_Array(idprop), sizeof(float) * idprop->len);
3262 }
3263 else {
3264 for (i = 0; i < idprop->len; i++) {
3265 values[i] = float(((double *)IDP_Array(idprop))[i]);
3266 }
3267 }
3268 }
3269 else if (prop->arraydimension == 0) {
3270 values[0] = RNA_property_float_get(ptr, prop);
3271 }
3272 else if (fprop->getarray) {
3273 fprop->getarray(ptr, values);
3274 }
3275 else if (fprop->getarray_ex) {
3276 fprop->getarray_ex(ptr, prop, values);
3277 }
3278 else {
3280 }
3281}
3282
3284{
3285 const int array_len = RNA_property_array_length(ptr, prop);
3286
3287 if (array_len <= 0) {
3288 values[0] = 0.0f;
3289 values[1] = 0.0f;
3290 }
3291 else if (array_len == 1) {
3292 RNA_property_float_get_array(ptr, prop, values);
3293 values[1] = values[0];
3294 }
3295 else {
3296 float arr_stack[32];
3297 float *arr;
3298 int i;
3299
3300 if (array_len > 32) {
3301 arr = static_cast<float *>(MEM_mallocN(sizeof(float) * array_len, __func__));
3302 }
3303 else {
3304 arr = arr_stack;
3305 }
3306
3308 values[0] = values[1] = arr[0];
3309 for (i = 1; i < array_len; i++) {
3310 values[0] = std::min(values[0], arr[i]);
3311 values[1] = std::max(values[1], arr[i]);
3312 }
3313
3314 if (arr != arr_stack) {
3315 MEM_freeN(arr);
3316 }
3317 }
3318}
3319
3321{
3322 float tmp[RNA_MAX_ARRAY_LENGTH];
3324
3326 BLI_assert(RNA_property_array_check(prop) != false);
3327 BLI_assert(index >= 0);
3328 BLI_assert(index < len);
3329
3330 if (len <= RNA_MAX_ARRAY_LENGTH) {
3332 return tmp[index];
3333 }
3334 float *tmparray, value;
3335
3336 tmparray = static_cast<float *>(MEM_mallocN(sizeof(float) * len, __func__));
3337 RNA_property_float_get_array(ptr, prop, tmparray);
3338 value = tmparray[index];
3339 MEM_freeN(tmparray);
3340
3341 return value;
3342}
3343
3344void RNA_property_float_set_array(PointerRNA *ptr, PropertyRNA *prop, const float *values)
3345{
3346 FloatPropertyRNA *fprop = (FloatPropertyRNA *)prop;
3347 IDProperty *idprop;
3348 int i;
3349
3351 BLI_assert(RNA_property_array_check(prop) != false);
3352
3353 if ((idprop = rna_idproperty_check(&prop, ptr))) {
3354 BLI_assert(idprop->len == RNA_property_array_length(ptr, prop) ||
3355 (prop->flag & PROP_IDPROPERTY));
3356 if (prop->arraydimension == 0) {
3357 if (idprop->type == IDP_FLOAT) {
3358 IDP_Float(idprop) = values[0];
3359 }
3360 else {
3361 IDP_Double(idprop) = values[0];
3362 }
3363 }
3364 else if (idprop->subtype == IDP_FLOAT) {
3365 memcpy(IDP_Array(idprop), values, sizeof(float) * idprop->len);
3366 }
3367 else {
3368 for (i = 0; i < idprop->len; i++) {
3369 ((double *)IDP_Array(idprop))[i] = values[i];
3370 }
3371 }
3372
3373 rna_idproperty_touch(idprop);
3374 }
3375 else if (prop->arraydimension == 0) {
3376 RNA_property_float_set(ptr, prop, values[0]);
3377 }
3378 else if (fprop->setarray) {
3379 fprop->setarray(ptr, values);
3380 }
3381 else if (fprop->setarray_ex) {
3382 fprop->setarray_ex(ptr, prop, values);
3383 }
3384 else if (prop->flag & PROP_EDITABLE) {
3385 // RNA_property_float_clamp_array(ptr, prop, &value); /* TODO. */
3386 if (IDProperty *group = RNA_struct_idprops(ptr, true)) {
3387 IDP_AddToGroup(group,
3389 blender::Span(values, prop->totarraylength),
3391 .release());
3392 }
3393 }
3394}
3395
3396void RNA_property_float_set_index(PointerRNA *ptr, PropertyRNA *prop, int index, float value)
3397{
3398 float tmp[RNA_MAX_ARRAY_LENGTH];
3400
3402 BLI_assert(RNA_property_array_check(prop) != false);
3403 BLI_assert(index >= 0);
3404 BLI_assert(index < len);
3405
3406 if (len <= RNA_MAX_ARRAY_LENGTH) {
3408 tmp[index] = value;
3410 }
3411 else {
3412 float *tmparray;
3413
3414 tmparray = static_cast<float *>(MEM_mallocN(sizeof(float) * len, __func__));
3415 RNA_property_float_get_array(ptr, prop, tmparray);
3416 tmparray[index] = value;
3417 RNA_property_float_set_array(ptr, prop, tmparray);
3418 MEM_freeN(tmparray);
3419 }
3420}
3421
3423{
3425
3427 BLI_assert(RNA_property_array_check(prop) == false);
3428
3429 if (prop->magic != RNA_MAGIC) {
3430 const IDProperty *idprop = (const IDProperty *)prop;
3431 if (idprop->ui_data) {
3433 const IDPropertyUIDataFloat *ui_data = (const IDPropertyUIDataFloat *)idprop->ui_data;
3434 return float(ui_data->default_value);
3435 }
3436 }
3437 if (fprop->get_default) {
3438 return fprop->get_default(ptr, prop);
3439 }
3440
3441 return fprop->defaultvalue;
3442}
3443
3445{
3446 if (prop->magic == RNA_MAGIC) {
3447 return false;
3448 }
3449
3450 IDProperty *idprop = (IDProperty *)prop;
3451 BLI_assert(idprop->type == IDP_FLOAT);
3452
3454 ui_data->default_value = double(value);
3455 return true;
3456}
3457
3459{
3461
3463 BLI_assert(RNA_property_array_check(prop) != false);
3464
3465 if (prop->magic != RNA_MAGIC) {
3466 int length = rna_ensure_property_array_length(ptr, prop);
3467
3468 const IDProperty *idprop = (const IDProperty *)prop;
3469 if (idprop->ui_data) {
3470 BLI_assert(idprop->type == IDP_ARRAY);
3472 const IDPropertyUIDataFloat *ui_data = (const IDPropertyUIDataFloat *)idprop->ui_data;
3474 ui_data->default_array_len,
3475 ui_data->default_value,
3476 length,
3477 values);
3478 }
3479 }
3480 else if (prop->arraydimension == 0) {
3481 values[0] = fprop->defaultvalue;
3482 }
3483 else {
3485 }
3486}
3487
3489{
3490 float tmp[RNA_MAX_ARRAY_LENGTH];
3492
3494 BLI_assert(RNA_property_array_check(prop) != false);
3495 BLI_assert(index >= 0);
3496 BLI_assert(index < len);
3497
3498 if (len <= RNA_MAX_ARRAY_LENGTH) {
3500 return tmp[index];
3501 }
3502 float *tmparray, value;
3503
3504 tmparray = static_cast<float *>(MEM_mallocN(sizeof(float) * len, __func__));
3506 value = tmparray[index];
3507 MEM_freeN(tmparray);
3508
3509 return value;
3510}
3511
3513{
3514 StringPropertyRNA *sprop = reinterpret_cast<StringPropertyRNA *>(prop);
3515 IDProperty *idprop;
3516
3518
3519 if ((idprop = rna_idproperty_check(&prop, ptr))) {
3520 /* NOTE: `std::string` does support NULL char in its data. */
3521 return std::string{IDP_String(idprop), size_t(idprop->len)};
3522 }
3523
3524 if (!sprop->get && !sprop->get_ex) {
3525 return std::string{sprop->defaultvalue};
3526 }
3527
3528 size_t length = size_t(RNA_property_string_length(ptr, prop));
3529 std::string string_ret{};
3530 string_ret.reserve(length + 1);
3531
3532 if (sprop->get) {
3533 sprop->get(ptr, string_ret.data());
3534 }
3535 else { /* if (sprop->get_ex) */
3536 sprop->get_ex(ptr, prop, string_ret.data());
3537 }
3538
3539 return string_ret;
3540}
3541
3543{
3544 StringPropertyRNA *sprop = (StringPropertyRNA *)prop;
3545 IDProperty *idprop;
3546
3548
3549 if ((idprop = rna_idproperty_check(&prop, ptr))) {
3550 /* editing bytes is not 100% supported
3551 * since they can contain NIL chars */
3552 if (idprop->subtype == IDP_STRING_SUB_BYTE) {
3553 memcpy(value, IDP_String(idprop), idprop->len);
3554 value[idprop->len] = '\0';
3555 }
3556 else {
3557 memcpy(value, IDP_String(idprop), idprop->len);
3558 }
3559 }
3560 else if (sprop->get) {
3561 sprop->get(ptr, value);
3562 }
3563 else if (sprop->get_ex) {
3564 sprop->get_ex(ptr, prop, value);
3565 }
3566 else {
3567 strcpy(value, sprop->defaultvalue);
3568 }
3569}
3570
3572 PointerRNA *ptr, PropertyRNA *prop, char *fixedbuf, int fixedlen, int *r_len)
3573{
3574 if (fixedbuf) {
3575 BLI_string_debug_size(fixedbuf, fixedlen);
3576 }
3577
3578 char *buf;
3579 int length;
3580
3582
3583 length = RNA_property_string_length(ptr, prop);
3584
3585 if (length + 1 < fixedlen) {
3586 buf = fixedbuf;
3587 }
3588 else {
3589 buf = static_cast<char *>(MEM_mallocN(sizeof(char) * (length + 1), __func__));
3590 }
3591
3592#ifndef NDEBUG
3593 /* safety check to ensure the string is actually set */
3594 buf[length] = 255;
3595#endif
3596
3597 RNA_property_string_get(ptr, prop, buf);
3598
3599#ifndef NDEBUG
3600 BLI_assert(buf[length] == '\0');
3601#endif
3602
3603 if (r_len) {
3604 *r_len = length;
3605 }
3606
3607 return buf;
3608}
3609
3611{
3612 StringPropertyRNA *sprop = (StringPropertyRNA *)prop;
3613 IDProperty *idprop;
3614
3616
3617 if ((idprop = rna_idproperty_check(&prop, ptr))) {
3618 if (idprop->subtype == IDP_STRING_SUB_BYTE) {
3619 return idprop->len;
3620 }
3621#ifndef NDEBUG
3622 /* these _must_ stay in sync */
3623 BLI_assert(strlen(IDP_String(idprop)) == idprop->len - 1);
3624#endif
3625 return idprop->len - 1;
3626 }
3627 if (sprop->length) {
3628 return sprop->length(ptr);
3629 }
3630 if (sprop->length_ex) {
3631 return sprop->length_ex(ptr, prop);
3632 }
3633 return strlen(sprop->defaultvalue);
3634}
3635
3636void RNA_property_string_set(PointerRNA *ptr, PropertyRNA *prop, const char *value)
3637{
3638 StringPropertyRNA *sprop = (StringPropertyRNA *)prop;
3639 IDProperty *idprop;
3640
3642
3643 if ((idprop = rna_idproperty_check(&prop, ptr))) {
3644 /* both IDP_STRING_SUB_BYTE / IDP_STRING_SUB_UTF8 */
3646 rna_idproperty_touch(idprop);
3647 }
3648 else if (sprop->set) {
3649 sprop->set(ptr, value); /* set function needs to clamp itself */
3650 }
3651 else if (sprop->set_ex) {
3652 sprop->set_ex(ptr, prop, value); /* set function needs to clamp itself */
3653 }
3654 else if (prop->flag & PROP_EDITABLE) {
3655 IDProperty *group;
3656
3657 group = RNA_struct_idprops(ptr, true);
3658 if (group) {
3660 group,
3663 }
3664 }
3665}
3666
3667void RNA_property_string_set_bytes(PointerRNA *ptr, PropertyRNA *prop, const char *value, int len)
3668{
3669 StringPropertyRNA *sprop = (StringPropertyRNA *)prop;
3670 IDProperty *idprop;
3671
3674
3675 if ((idprop = rna_idproperty_check(&prop, ptr))) {
3676 IDP_ResizeArray(idprop, len);
3677 memcpy(idprop->data.pointer, value, size_t(len));
3678
3679 rna_idproperty_touch(idprop);
3680 }
3681 else if (sprop->set) {
3682 /* XXX, should take length argument (currently not used). */
3683 sprop->set(ptr, value); /* set function needs to clamp itself */
3684 }
3685 else if (sprop->set_ex) {
3686 /* XXX, should take length argument (currently not used). */
3687 sprop->set_ex(ptr, prop, value); /* set function needs to clamp itself */
3688 }
3689 else if (prop->flag & PROP_EDITABLE) {
3690 IDProperty *group;
3691
3692 group = RNA_struct_idprops(ptr, true);
3693 if (group) {
3694 IDPropertyTemplate val = {0};
3695 val.string.str = value;
3696 val.string.len = len;
3699 }
3700 }
3701}
3702
3703void RNA_property_string_get_default(PropertyRNA *prop, char *value, const int value_maxncpy)
3704{
3706
3707 if (prop->magic != RNA_MAGIC) {
3708 const IDProperty *idprop = (const IDProperty *)prop;
3709 if (idprop->ui_data) {
3710 BLI_assert(idprop->type == IDP_STRING);
3711 const IDPropertyUIDataString *ui_data = (const IDPropertyUIDataString *)idprop->ui_data;
3712 BLI_strncpy(value, ui_data->default_value, value_maxncpy);
3713 return;
3714 }
3715
3716 strcpy(value, "");
3717 return;
3718 }
3719
3721
3722 strcpy(value, sprop->defaultvalue);
3723}
3724
3726 PointerRNA *ptr, PropertyRNA *prop, char *fixedbuf, int fixedlen, int *r_len)
3727{
3728 char *buf;
3729 int length;
3730
3732
3734
3735 if (length + 1 < fixedlen) {
3736 buf = fixedbuf;
3737 }
3738 else {
3739 buf = static_cast<char *>(MEM_callocN(sizeof(char) * (length + 1), __func__));
3740 }
3741
3742 RNA_property_string_get_default(prop, buf, length + 1);
3743
3744 if (r_len) {
3745 *r_len = length;
3746 }
3747
3748 return buf;
3749}
3750
3752{
3754
3755 if (prop->magic != RNA_MAGIC) {
3756 const IDProperty *idprop = (const IDProperty *)prop;
3757 if (idprop->ui_data) {
3758 BLI_assert(idprop->type == IDP_STRING);
3759 const IDPropertyUIDataString *ui_data = (const IDPropertyUIDataString *)idprop->ui_data;
3760 if (ui_data->default_value != nullptr) {
3761 return strlen(ui_data->default_value);
3762 }
3763 }
3764
3765 return 0;
3766 }
3767
3769
3770 return strlen(sprop->defaultvalue);
3771}
3772
3774{
3776 if (prop->magic != RNA_MAGIC) {
3777 return eStringPropertySearchFlag(0);
3778 }
3780 if (sprop->search) {
3782 }
3783 else {
3784 BLI_assert(sprop->search_flag == 0);
3785 }
3786 return sprop->search_flag;
3787}
3788
3790 const bContext *C,
3791 PointerRNA *ptr,
3792 PropertyRNA *prop,
3793 const char *edit_text,
3795{
3798 sprop->search(C, ptr, prop, edit_text, visit_fn);
3799}
3800
3802{
3803 EnumPropertyRNA *eprop = (EnumPropertyRNA *)prop;
3804 IDProperty *idprop;
3805
3807
3808 if ((idprop = rna_idproperty_check(&prop, ptr))) {
3809 return IDP_Int(idprop);
3810 }
3811 if (eprop->get) {
3812 return eprop->get(ptr);
3813 }
3814 if (eprop->get_ex) {
3815 return eprop->get_ex(ptr, prop);
3816 }
3817 return eprop->defaultvalue;
3818}
3819
3821{
3822 EnumPropertyRNA *eprop = (EnumPropertyRNA *)prop;
3823 IDProperty *idprop;
3824
3826
3827 if ((idprop = rna_idproperty_check(&prop, ptr))) {
3828 IDP_Int(idprop) = value;
3829 rna_idproperty_touch(idprop);
3830 }
3831 else if (eprop->set) {
3832 eprop->set(ptr, value);
3833 }
3834 else if (eprop->set_ex) {
3835 eprop->set_ex(ptr, prop, value);
3836 }
3837 else if (prop->flag & PROP_EDITABLE) {
3838 IDPropertyTemplate val = {0};
3839 IDProperty *group;
3840
3841 val.i = value;
3842
3843 group = RNA_struct_idprops(ptr, true);
3844 if (group) {
3846 }
3847 }
3848}
3849
3851{
3853
3855
3856 return eprop->defaultvalue;
3857}
3858
3860 const bContext *C, PointerRNA *ptr, PropertyRNA *prop, int from_value, int step)
3861{
3862 const EnumPropertyItem *item_array;
3863 int totitem;
3864 bool free;
3865 int result_value = from_value;
3866 int i, i_init;
3867 int single_step = (step < 0) ? -1 : 1;
3868 int step_tot = 0;
3869
3870 RNA_property_enum_items((bContext *)C, ptr, prop, &item_array, &totitem, &free);
3871 i = RNA_enum_from_value(item_array, from_value);
3872 i_init = i;
3873
3874 do {
3875 i = mod_i(i + single_step, totitem);
3876 if (item_array[i].identifier[0]) {
3877 step_tot += single_step;
3878 }
3879 } while ((i != i_init) && (step_tot != step));
3880
3881 if (i != i_init) {
3882 result_value = item_array[i].value;
3883 }
3884
3885 if (free) {
3886 MEM_freeN((void *)item_array);
3887 }
3888
3889 return result_value;
3890}
3891
3893{
3894 PointerPropertyRNA *pprop = (PointerPropertyRNA *)prop;
3895 IDProperty *idprop;
3896
3898
3900
3901 if ((idprop = rna_idproperty_check(&prop, ptr))) {
3902 pprop = (PointerPropertyRNA *)prop;
3903
3904 if (RNA_struct_is_ID(pprop->type)) {
3905 return rna_pointer_inherit_refine(ptr, pprop->type, IDP_Id(idprop));
3906 }
3907
3908 /* for groups, data is idprop itself */
3909 if (pprop->type_fn) {
3910 return rna_pointer_inherit_refine(ptr, pprop->type_fn(ptr), idprop);
3911 }
3912 return rna_pointer_inherit_refine(ptr, pprop->type, idprop);
3913 }
3914 if (pprop->get) {
3915 return pprop->get(ptr);
3916 }
3917 if (prop->flag & PROP_IDPROPERTY) {
3918 /* NOTE: While creating/writing data in an accessor is really bad design-wise, this is
3919 * currently very difficult to avoid in that case. So a global mutex is used to keep ensuring
3920 * thread safety. */
3922 /* NOTE: We do not need to check again for existence of the pointer after locking here, since
3923 * this is also done in #RNA_property_pointer_add itself. */
3926 return RNA_property_pointer_get(ptr, prop);
3927 }
3928 return PointerRNA_NULL;
3929}
3930
3932 PropertyRNA *prop,
3933 PointerRNA ptr_value,
3934 ReportList *reports)
3935{
3936 /* Detect IDProperty and retrieve the actual PropertyRNA pointer before cast. */
3937 IDProperty *idprop = rna_idproperty_check(&prop, ptr);
3938
3939 PointerPropertyRNA *pprop = (PointerPropertyRNA *)prop;
3941
3942 /* This is a 'real' RNA property, not an IDProperty or a dynamic RNA property using an IDProperty
3943 * as backend storage. */
3944 if (pprop->set) {
3945 if (ptr_value.type != nullptr && !RNA_struct_is_a(ptr_value.type, pprop->type)) {
3946 BKE_reportf(reports,
3947 RPT_ERROR,
3948 "%s: expected %s type, not %s",
3949 __func__,
3950 pprop->type->identifier,
3951 ptr_value.type->identifier);
3952 return;
3953 }
3954 if (!((prop->flag & PROP_NEVER_NULL) && ptr_value.data == nullptr) &&
3955 !((prop->flag & PROP_ID_SELF_CHECK) && ptr->owner_id == ptr_value.owner_id))
3956 {
3957 pprop->set(ptr, ptr_value, reports);
3958 }
3959 return;
3960 }
3961
3962 /* Assigning to an IDProperty. */
3963 ID *value = static_cast<ID *>(ptr_value.data);
3964
3965 if (ptr_value.type != nullptr && !RNA_struct_is_a(ptr_value.type, &RNA_ID)) {
3967 reports, RPT_ERROR, "%s: expected ID type, not %s", __func__, ptr_value.type->identifier);
3968 return;
3969 }
3970 if (value && (value->flag & ID_FLAG_EMBEDDED_DATA) != 0) {
3971 BKE_reportf(reports, RPT_ERROR, "%s: cannot assign an embedded ID to an IDProperty", __func__);
3972 return;
3973 }
3974
3975 /* We got an existing IDProperty. */
3976 if (idprop != nullptr) {
3977 /* Not-yet-defined ID IDProps have an IDP_GROUP type, not an IDP_ID one - because of reasons?
3978 * XXX This has to be investigated fully - there might be a good reason for it, but off hands
3979 * this seems really weird... */
3980 if (idprop->type == IDP_ID) {
3981 IDP_AssignID(idprop, value, 0);
3982 rna_idproperty_touch(idprop);
3983 }
3984 else {
3985 BLI_assert(idprop->type == IDP_GROUP);
3986 IDProperty *group = RNA_struct_idprops(ptr, true);
3987 BLI_assert(group != nullptr);
3988
3990 group,
3991 blender::bke::idprop::create(idprop->name, value, IDP_FLAG_STATIC_TYPE).release(),
3992 idprop);
3993 }
3994 }
3995 /* IDProperty disguised as RNA property (and not yet defined in ptr). */
3996 else if (prop->flag & PROP_EDITABLE) {
3997 if (IDProperty *group = RNA_struct_idprops(ptr, true)) {
3999 group,
4001 }
4002 }
4003}
4004
4006{
4007 // PointerPropertyRNA *pprop = (PointerPropertyRNA *)prop;
4008
4009 // BLI_assert(RNA_property_type(prop) == PROP_POINTER);
4010
4011 return PointerRNA_NULL; /* FIXME: there has to be a way... */
4012}
4013
4015{
4016 // IDProperty *idprop;
4017
4019
4020 if (/*idprop=*/rna_idproperty_check(&prop, ptr)) {
4021 /* already exists */
4022 }
4023 else if (prop->flag & PROP_IDPROPERTY) {
4024 IDProperty *group;
4025
4026 group = RNA_struct_idprops(ptr, true);
4027 if (group) {
4029 group,
4031 }
4032 }
4033 else {
4034 printf("%s %s.%s: only supported for id properties.\n",
4035 __func__,
4037 prop->identifier);
4038 }
4039}
4040
4042{
4043 IDProperty *idprop, *group;
4044
4046
4047 if ((idprop = rna_idproperty_check(&prop, ptr))) {
4048 group = RNA_struct_idprops(ptr, false);
4049
4050 if (group) {
4051 IDP_FreeFromGroup(group, idprop);
4052 }
4053 }
4054 else {
4055 printf("%s %s.%s: only supported for id properties.\n",
4056 __func__,
4058 prop->identifier);
4059 }
4060}
4061
4063{
4065
4066 iter->ptr.data = rna_iterator_array_get(iter);
4067 iter->ptr.type = cprop->item_type;
4068 rna_pointer_inherit_id(cprop->item_type, &iter->parent, &iter->ptr);
4069}
4070
4072 PropertyRNA *prop,
4074{
4075 IDProperty *idprop;
4076
4078
4079 *iter = {};
4080
4081 if ((idprop = rna_idproperty_check(&prop, ptr)) || (prop->flag & PROP_IDPROPERTY)) {
4082 iter->parent = *ptr;
4083 iter->prop = prop;
4084
4085 if (idprop) {
4087 iter, IDP_IDPArray(idprop), sizeof(IDProperty), idprop->len, false, nullptr);
4088 }
4089 else {
4090 rna_iterator_array_begin(iter, nullptr, sizeof(IDProperty), 0, false, nullptr);
4091 }
4092
4093 if (iter->valid) {
4095 }
4096
4097 iter->idprop = 1;
4098 }
4099 else {
4101 cprop->begin(iter, ptr);
4102 }
4103}
4104
4106{
4108
4109 if (iter->idprop) {
4111
4112 if (iter->valid) {
4114 }
4115 }
4116 else {
4117 cprop->next(iter);
4118 }
4119}
4120
4122{
4124 int i;
4125
4126 if (num > 1 && (iter->idprop || (cprop->property.flag_internal & PROP_INTERN_RAW_ARRAY))) {
4127 /* fast skip for array */
4128 ArrayIterator *internal = &iter->internal.array;
4129
4130 if (!internal->skip) {
4131 internal->ptr += internal->itemsize * (num - 1);
4132 iter->valid = (internal->ptr < internal->endptr);
4133 if (iter->valid) {
4135 }
4136 return;
4137 }
4138 }
4139
4140 /* slow iteration otherwise */
4141 for (i = 0; i < num && iter->valid; i++) {
4143 }
4144}
4145
4147{
4149
4150 if (iter->idprop) {
4152 }
4153 else {
4154 cprop->end(iter);
4155 }
4156}
4157
4159{
4161 IDProperty *idprop;
4162
4164
4165 if ((idprop = rna_idproperty_check(&prop, ptr))) {
4166 return idprop->len;
4167 }
4168 if (cprop->length) {
4169 return cprop->length(ptr);
4170 }
4172 int length = 0;
4173
4174 RNA_property_collection_begin(ptr, prop, &iter);
4175 for (; iter.valid; RNA_property_collection_next(&iter)) {
4176 length++;
4177 }
4179
4180 return length;
4181}
4182
4184{
4187 RNA_property_collection_begin(ptr, prop, &iter);
4188 bool test = iter.valid;
4190 return !test;
4191}
4192
4193/* This helper checks whether given collection property itself is editable (we only currently
4194 * support a limited set of operations, insertion of new items, and re-ordering of those new items
4195 * exclusively). */
4197 PropertyRNA *prop,
4198 bool *r_is_liboverride)
4199{
4200 ID *id = ptr->owner_id;
4201 if (id == nullptr) {
4202 *r_is_liboverride = false;
4203 return true;
4204 }
4205
4206 const bool is_liboverride = *r_is_liboverride = ID_IS_OVERRIDE_LIBRARY(id);
4207
4208 if (!is_liboverride) {
4209 /* We return True also for linked data, as it allows tricks like py scripts 'overriding' data
4210 * of those. */
4211 return true;
4212 }
4213
4214 if (!RNA_property_overridable_get(ptr, prop)) {
4215 return false;
4216 }
4217
4218 if (prop->magic != RNA_MAGIC || (prop->flag & PROP_IDPROPERTY) == 0) {
4219 /* Insertion and such not supported for pure IDProperties for now, nor for pure RNA/DNA ones.
4220 */
4221 return false;
4222 }
4223 if ((prop->flag_override & PROPOVERRIDE_LIBRARY_INSERTION) == 0) {
4224 return false;
4225 }
4226
4227 /* No more checks to do, this collections is overridable. */
4228 return true;
4229}
4230
4232{
4233 IDProperty *idprop;
4234 // CollectionPropertyRNA *cprop = (CollectionPropertyRNA *)prop;
4235
4237
4238 bool is_liboverride;
4239 if (!property_collection_liboverride_editable(ptr, prop, &is_liboverride)) {
4240 if (r_ptr) {
4241 *r_ptr = {};
4242 }
4243 return;
4244 }
4245
4246 if ((idprop = rna_idproperty_check(&prop, ptr))) {
4247 IDProperty *item;
4248
4250 if (is_liboverride) {
4252 }
4253 IDP_AppendArray(idprop, item);
4254 /* IDP_AppendArray does a shallow copy (memcpy), only free memory. */
4255 // IDP_FreePropertyContent(item);
4256 MEM_freeN(item);
4257 rna_idproperty_touch(idprop);
4258 }
4259 else if (prop->flag & PROP_IDPROPERTY) {
4260 IDProperty *group, *item;
4261
4262 group = RNA_struct_idprops(ptr, true);
4263 if (group) {
4264 idprop = IDP_NewIDPArray(prop->identifier);
4265 IDP_AddToGroup(group, idprop);
4266
4268 if (is_liboverride) {
4270 }
4271 IDP_AppendArray(idprop, item);
4272 /* #IDP_AppendArray does a shallow copy (memcpy), only free memory. */
4273 // IDP_FreePropertyContent(item);
4274 MEM_freeN(item);
4275 }
4276 }
4277
4278 if (r_ptr) {
4279 if (idprop) {
4281
4282 r_ptr->data = IDP_GetIndexArray(idprop, idprop->len - 1);
4283 r_ptr->type = cprop->item_type;
4284 rna_pointer_inherit_id(nullptr, ptr, r_ptr);
4285 }
4286 else {
4287 *r_ptr = {};
4288 }
4289 }
4290}
4291
4293{
4294 IDProperty *idprop;
4295 // CollectionPropertyRNA *cprop = (CollectionPropertyRNA *)prop;
4296
4298
4299 bool is_liboverride;
4300 if (!property_collection_liboverride_editable(ptr, prop, &is_liboverride)) {
4301 return false;
4302 }
4303
4304 if ((idprop = rna_idproperty_check(&prop, ptr))) {
4305 IDProperty tmp, *array;
4306 int len;
4307
4308 len = idprop->len;
4309 array = IDP_IDPArray(idprop);
4310
4311 if (key >= 0 && key < len) {
4312 if (is_liboverride && (array[key].flag & IDP_FLAG_OVERRIDELIBRARY_LOCAL) == 0) {
4313 /* We can only remove items that we actually inserted in the local override. */
4314 return false;
4315 }
4316
4317 if (key + 1 < len) {
4318 /* move element to be removed to the back */
4319 memcpy(&tmp, &array[key], sizeof(IDProperty));
4320 memmove(array + key, array + key + 1, sizeof(IDProperty) * (len - (key + 1)));
4321 memcpy(&array[len - 1], &tmp, sizeof(IDProperty));
4322 }
4323
4324 IDP_ResizeIDPArray(idprop, len - 1);
4325 }
4326
4327 return true;
4328 }
4329 if (prop->flag & PROP_IDPROPERTY) {
4330 return true;
4331 }
4332
4333 return false;
4334}
4335
4337{
4338 IDProperty *idprop;
4339
4341
4342 bool is_liboverride;
4343 if (!property_collection_liboverride_editable(ptr, prop, &is_liboverride)) {
4344 return false;
4345 }
4346
4347 if ((idprop = rna_idproperty_check(&prop, ptr))) {
4348 IDProperty tmp, *array;
4349 int len;
4350
4351 len = idprop->len;
4352 array = IDP_IDPArray(idprop);
4353
4354 if (key >= 0 && key < len && pos >= 0 && pos < len && key != pos) {
4355 if (is_liboverride && (array[key].flag & IDP_FLAG_OVERRIDELIBRARY_LOCAL) == 0) {
4356 /* We can only move items that we actually inserted in the local override. */
4357 return false;
4358 }
4359
4360 memcpy(&tmp, &array[key], sizeof(IDProperty));
4361 if (pos < key) {
4362 memmove(array + pos + 1, array + pos, sizeof(IDProperty) * (key - pos));
4363 }
4364 else {
4365 memmove(array + key, array + key + 1, sizeof(IDProperty) * (pos - key));
4366 }
4367 memcpy(&array[pos], &tmp, sizeof(IDProperty));
4368 }
4369
4370 return true;
4371 }
4372 if (prop->flag & PROP_IDPROPERTY) {
4373 return true;
4374 }
4375
4376 return false;
4377}
4378
4380{
4381 IDProperty *idprop;
4382
4384
4385 bool is_liboverride;
4386 if (!property_collection_liboverride_editable(ptr, prop, &is_liboverride)) {
4387 return;
4388 }
4389
4390 if ((idprop = rna_idproperty_check(&prop, ptr))) {
4391 if (is_liboverride) {
4392 /* We can only move items that we actually inserted in the local override. */
4393 int len = idprop->len;
4394 IDProperty tmp, *array = IDP_IDPArray(idprop);
4395 for (int i = 0; i < len; i++) {
4396 if ((array[i].flag & IDP_FLAG_OVERRIDELIBRARY_LOCAL) != 0) {
4397 memcpy(&tmp, &array[i], sizeof(IDProperty));
4398 memmove(array + i, array + i + 1, sizeof(IDProperty) * (len - (i + 1)));
4399 memcpy(&array[len - 1], &tmp, sizeof(IDProperty));
4400 IDP_ResizeIDPArray(idprop, --len);
4401 i--;
4402 }
4403 }
4404 }
4405 else {
4406 IDP_ResizeIDPArray(idprop, 0);
4407 }
4408 rna_idproperty_touch(idprop);
4409 }
4410}
4411
4413 PropertyRNA *prop,
4414 const PointerRNA *t_ptr)
4415{
4417 int index = 0;
4418
4420
4421 RNA_property_collection_begin(ptr, prop, &iter);
4422 for (index = 0; iter.valid; RNA_property_collection_next(&iter), index++) {
4423 if (iter.ptr.data == t_ptr->data) {
4424 break;
4425 }
4426 }
4428
4429 /* did we find it? */
4430 if (iter.valid) {
4431 return index;
4432 }
4433 return -1;
4434}
4435
4442
4449
4456
4462
4464 PropertyRNA *prop,
4465 int key,
4466 PointerRNA *r_ptr)
4467{
4469
4471
4472 if (cprop->lookupint) {
4473 /* we have a callback defined, use it */
4474 return cprop->lookupint(ptr, key, r_ptr);
4475 }
4476 /* no callback defined, just iterate and find the nth item */
4478 int i;
4479
4480 RNA_property_collection_begin(ptr, prop, &iter);
4481 for (i = 0; iter.valid; RNA_property_collection_next(&iter), i++) {
4482 if (i == key) {
4483 *r_ptr = iter.ptr;
4484 break;
4485 }
4486 }
4488
4489 if (!iter.valid) {
4490 *r_ptr = {};
4491 }
4492
4493 return iter.valid;
4494}
4495
4497 PointerRNA *ptr, PropertyRNA *prop, const char *key, PointerRNA *r_ptr, int *r_index)
4498{
4500
4502
4503 if (!key) {
4504 *r_index = -1;
4505 *r_ptr = PointerRNA_NULL;
4506 return false;
4507 }
4508
4509 if (cprop->lookupstring) {
4510 /* we have a callback defined, use it */
4511 return cprop->lookupstring(ptr, key, r_ptr);
4512 }
4513 /* no callback defined, compare with name properties if they exist */
4515 PropertyRNA *nameprop;
4516 char name_buf[256], *name;
4517 bool found = false;
4518 int keylen = strlen(key);
4519 int namelen;
4520 int index = 0;
4521
4522 RNA_property_collection_begin(ptr, prop, &iter);
4523 for (; iter.valid; RNA_property_collection_next(&iter), index++) {
4524 if (iter.ptr.data && iter.ptr.type->nameproperty) {
4525 nameprop = iter.ptr.type->nameproperty;
4526
4528 &iter.ptr, nameprop, name_buf, sizeof(name_buf), &namelen);
4529
4530 if ((keylen == namelen) && STREQ(name, key)) {
4531 *r_ptr = iter.ptr;
4532 found = true;
4533 }
4534
4535 if (name != name_buf) {
4536 MEM_freeN(name);
4537 }
4538
4539 if (found) {
4540 break;
4541 }
4542 }
4543 }
4545
4546 if (!iter.valid) {
4547 *r_ptr = {};
4548 *r_index = -1;
4549 }
4550 else {
4551 *r_index = index;
4552 }
4553
4554 return iter.valid;
4555}
4556
4558 PropertyRNA *prop,
4559 const char *key,
4560 PointerRNA *r_ptr)
4561{
4562 int index;
4563 return RNA_property_collection_lookup_string_index(ptr, prop, key, r_ptr, &index);
4564}
4565
4567 PropertyRNA *prop,
4568 const int key,
4569 const PointerRNA *assign_ptr)
4570{
4572
4574
4575 if (cprop->assignint) {
4576 /* we have a callback defined, use it */
4577 return cprop->assignint(ptr, key, assign_ptr);
4578 }
4579
4580 return false;
4581}
4582
4584{
4586
4587 *r_ptr = *ptr;
4588 return ((r_ptr->type = rna_ensure_property(prop)->srna) ? 1 : 0);
4589}
4590
4592 PointerRNA *ptr, PropertyRNA *prop, PropertyRNA *itemprop, bool set, RawArray *array)
4593{
4595 ArrayIterator *internal;
4596 char *arrayp;
4597
4599
4600 if (!(prop->flag_internal & PROP_INTERN_RAW_ARRAY) ||
4602 {
4603 return 0;
4604 }
4605
4606 RNA_property_collection_begin(ptr, prop, &iter);
4607
4608 if (iter.valid) {
4609 /* get data from array iterator and item property */
4610 internal = &iter.internal.array;
4611 arrayp = (iter.valid) ? static_cast<char *>(iter.ptr.data) : nullptr;
4612
4613 if (internal->skip || (set && !RNA_property_editable(&iter.ptr, itemprop))) {
4614 /* we might skip some items, so it's not a proper array */
4616 return 0;
4617 }
4618
4619 array->array = arrayp + itemprop->rawoffset;
4620 array->stride = internal->itemsize;
4621 array->len = ((char *)internal->endptr - arrayp) / internal->itemsize;
4622 array->type = itemprop->rawtype;
4623 }
4624 else {
4625 memset(array, 0, sizeof(RawArray));
4626 }
4627
4629
4630 return 1;
4631}
4632
4633#define RAW_GET(dtype, var, raw, a) \
4634 { \
4635 switch (raw.type) { \
4636 case PROP_RAW_CHAR: \
4637 var = (dtype)((char *)raw.array)[a]; \
4638 break; \
4639 case PROP_RAW_INT8: \
4640 var = (dtype)((int8_t *)raw.array)[a]; \
4641 break; \
4642 case PROP_RAW_UINT8: \
4643 var = (dtype)((uint8_t *)raw.array)[a]; \
4644 break; \
4645 case PROP_RAW_SHORT: \
4646 var = (dtype)((short *)raw.array)[a]; \
4647 break; \
4648 case PROP_RAW_UINT16: \
4649 var = (dtype)((uint16_t *)raw.array)[a]; \
4650 break; \
4651 case PROP_RAW_INT: \
4652 var = (dtype)((int *)raw.array)[a]; \
4653 break; \
4654 case PROP_RAW_BOOLEAN: \
4655 var = (dtype)((bool *)raw.array)[a]; \
4656 break; \
4657 case PROP_RAW_FLOAT: \
4658 var = (dtype)((float *)raw.array)[a]; \
4659 break; \
4660 case PROP_RAW_DOUBLE: \
4661 var = (dtype)((double *)raw.array)[a]; \
4662 break; \
4663 case PROP_RAW_INT64: \
4664 var = (dtype)((int64_t *)raw.array)[a]; \
4665 break; \
4666 case PROP_RAW_UINT64: \
4667 var = (dtype)((uint64_t *)raw.array)[a]; \
4668 break; \
4669 default: \
4670 var = (dtype)0; \
4671 } \
4672 } \
4673 (void)0
4674
4675#define RAW_SET(dtype, raw, a, var) \
4676 { \
4677 switch (raw.type) { \
4678 case PROP_RAW_CHAR: \
4679 ((char *)raw.array)[a] = char(var); \
4680 break; \
4681 case PROP_RAW_INT8: \
4682 ((int8_t *)raw.array)[a] = int8_t(var); \
4683 break; \
4684 case PROP_RAW_UINT8: \
4685 ((uint8_t *)raw.array)[a] = uint8_t(var); \
4686 break; \
4687 case PROP_RAW_SHORT: \
4688 ((short *)raw.array)[a] = short(var); \
4689 break; \
4690 case PROP_RAW_UINT16: \
4691 ((uint16_t *)raw.array)[a] = uint16_t(var); \
4692 break; \
4693 case PROP_RAW_INT: \
4694 ((int *)raw.array)[a] = int(var); \
4695 break; \
4696 case PROP_RAW_BOOLEAN: \
4697 ((bool *)raw.array)[a] = bool(var); \
4698 break; \
4699 case PROP_RAW_FLOAT: \
4700 ((float *)raw.array)[a] = float(var); \
4701 break; \
4702 case PROP_RAW_DOUBLE: \
4703 ((double *)raw.array)[a] = double(var); \
4704 break; \
4705 case PROP_RAW_INT64: \
4706 ((int64_t *)raw.array)[a] = int64_t(var); \
4707 break; \
4708 case PROP_RAW_UINT64: \
4709 ((uint64_t *)raw.array)[a] = uint64_t(var); \
4710 break; \
4711 default: \
4712 break; \
4713 } \
4714 } \
4715 (void)0
4716
4718{
4719 switch (type) {
4720 case PROP_RAW_CHAR:
4721 return sizeof(char);
4722 case PROP_RAW_INT8:
4723 return sizeof(int8_t);
4724 case PROP_RAW_UINT8:
4725 return sizeof(uint8_t);
4726 case PROP_RAW_SHORT:
4727 return sizeof(short);
4728 case PROP_RAW_UINT16:
4729 return sizeof(uint16_t);
4730 case PROP_RAW_INT:
4731 return sizeof(int);
4732 case PROP_RAW_BOOLEAN:
4733 return sizeof(bool);
4734 case PROP_RAW_FLOAT:
4735 return sizeof(float);
4736 case PROP_RAW_DOUBLE:
4737 return sizeof(double);
4738 case PROP_RAW_INT64:
4739 return sizeof(int64_t);
4740 case PROP_RAW_UINT64:
4741 return sizeof(uint64_t);
4742 default:
4743 return 0;
4744 }
4745}
4746
4748{
4750 const int dim = RNA_property_array_dimension(ptr, prop, len);
4751 int size;
4752
4753 if (dim == 0) {
4754 return 0;
4755 }
4756
4757 for (size = 1, i = 0; i < dim; i++) {
4758 size *= len[i];
4759 }
4760
4761 return size;
4762}
4763
4764static int rna_raw_access(ReportList *reports,
4765 PointerRNA *ptr,
4766 PropertyRNA *prop,
4767 const char *propname,
4768 void *inarray,
4769 RawPropertyType intype,
4770 int inlen,
4771 int set)
4772{
4773 StructRNA *ptype;
4774 PropertyRNA *itemprop, *iprop;
4775 PropertyType itemtype = PropertyType(0);
4776 RawArray in;
4777 int itemlen = 0;
4778
4779 /* initialize in array, stride assumed 0 in following code */
4780 in.array = inarray;
4781 in.type = intype;
4782 in.len = inlen;
4783 in.stride = 0;
4784
4785 ptype = RNA_property_pointer_type(ptr, prop);
4786
4787 /* try to get item property pointer */
4788 PointerRNA itemptr_base = RNA_pointer_create(nullptr, ptype, nullptr);
4789 itemprop = RNA_struct_find_property(&itemptr_base, propname);
4790
4791 if (itemprop) {
4792 /* we have item property pointer */
4793 RawArray out;
4794
4795 /* check type */
4796 itemtype = RNA_property_type(itemprop);
4797
4798 if (!ELEM(itemtype, PROP_BOOLEAN, PROP_INT, PROP_FLOAT, PROP_ENUM)) {
4799 BKE_report(reports, RPT_ERROR, "Only boolean, int, float, and enum properties supported");
4800 return 0;
4801 }
4802
4803 /* check item array */
4804 itemlen = RNA_property_array_length(&itemptr_base, itemprop);
4805
4806 /* dynamic array? need to get length per item */
4807 if (itemprop->getlength) {
4808 itemprop = nullptr;
4809 }
4810 /* try to access as raw array */
4811 else if (RNA_property_collection_raw_array(ptr, prop, itemprop, set, &out)) {
4812 int arraylen = (itemlen == 0) ? 1 : itemlen;
4813 if (in.len != arraylen * out.len) {
4814 BKE_reportf(reports,
4815 RPT_ERROR,
4816 "Array length mismatch (expected %d, got %d)",
4817 out.len * arraylen,
4818 in.len);
4819 return 0;
4820 }
4821
4822 /* matching raw types */
4823 if (out.type == in.type) {
4824 void *inp = in.array;
4825 void *outp = out.array;
4826 size_t size;
4827
4828 size = RNA_raw_type_sizeof(out.type) * arraylen;
4829
4830 if (size == out.stride) {
4831 /* The property is stored contiguously so the entire array can be copied at once. */
4832 if (set) {
4833 memcpy(outp, inp, size * out.len);
4834 }
4835 else {
4836 memcpy(inp, outp, size * out.len);
4837 }
4838 }
4839 else {
4840 for (int a = 0; a < out.len; a++) {
4841 if (set) {
4842 memcpy(outp, inp, size);
4843 }
4844 else {
4845 memcpy(inp, outp, size);
4846 }
4847
4848 inp = (char *)inp + size;
4849 outp = (char *)outp + out.stride;
4850 }
4851 }
4852
4853 return 1;
4854 }
4855
4856 /* Could also be faster with non-matching types,
4857 * for now we just do slower loop. */
4858 }
4859 BLI_assert_msg(itemlen == 0 || itemtype != PROP_ENUM,
4860 "Enum array properties should not exist");
4861 }
4862
4863 {
4864 void *tmparray = nullptr;
4865 int tmplen = 0;
4866 int err = 0, j, a = 0;
4867 int needconv = 1;
4868
4869 if (((itemtype == PROP_INT) && (in.type == PROP_RAW_INT)) ||
4870 ((itemtype == PROP_BOOLEAN) && (in.type == PROP_RAW_BOOLEAN)) ||
4871 ((itemtype == PROP_FLOAT) && (in.type == PROP_RAW_FLOAT)))
4872 {
4873 /* avoid creating temporary buffer if the data type match */
4874 needconv = 0;
4875 }
4876 /* no item property pointer, can still be id property, or
4877 * property of a type derived from the collection pointer type */
4878 RNA_PROP_BEGIN (ptr, itemptr, prop) {
4879 if (itemptr.data) {
4880 if (itemprop) {
4881 /* we got the property already */
4882 iprop = itemprop;
4883 }
4884 else {
4885 /* not yet, look it up and verify if it is valid */
4886 iprop = RNA_struct_find_property(&itemptr, propname);
4887
4888 if (iprop) {
4889 itemlen = rna_property_array_length_all_dimensions(&itemptr, iprop);
4890 itemtype = RNA_property_type(iprop);
4891 }
4892 else {
4893 BKE_reportf(reports, RPT_ERROR, "Property named '%s' not found", propname);
4894 err = 1;
4895 break;
4896 }
4897
4898 if (!ELEM(itemtype, PROP_BOOLEAN, PROP_INT, PROP_FLOAT, PROP_ENUM)) {
4899 BKE_report(
4900 reports, RPT_ERROR, "Only boolean, int, float and enum properties supported");
4901 err = 1;
4902 break;
4903 }
4904 BLI_assert_msg(itemlen == 0 || itemtype != PROP_ENUM,
4905 "Enum array properties should not exist");
4906 }
4907
4908 /* editable check */
4909 if (!set || RNA_property_editable(&itemptr, iprop)) {
4910 if (a + itemlen > in.len) {
4912 reports, RPT_ERROR, "Array length mismatch (got %d, expected more)", in.len);
4913 err = 1;
4914 break;
4915 }
4916
4917 if (itemlen == 0) {
4918 /* handle conversions */
4919 if (set) {
4920 switch (itemtype) {
4921 case PROP_BOOLEAN: {
4922 int b;
4923 RAW_GET(bool, b, in, a);
4924 RNA_property_boolean_set(&itemptr, iprop, b);
4925 break;
4926 }
4927 case PROP_INT: {
4928 int i;
4929 RAW_GET(int, i, in, a);
4930 RNA_property_int_set(&itemptr, iprop, i);
4931 break;
4932 }
4933 case PROP_FLOAT: {
4934 float f;
4935 RAW_GET(float, f, in, a);
4936 RNA_property_float_set(&itemptr, iprop, f);
4937 break;
4938 }
4939 case PROP_ENUM: {
4940 int i;
4941 RAW_GET(int, i, in, a);
4942 RNA_property_enum_set(&itemptr, iprop, i);
4943 break;
4944 }
4945 default:
4947 break;
4948 }
4949 }
4950 else {
4951 switch (itemtype) {
4952 case PROP_BOOLEAN: {
4953 int b = RNA_property_boolean_get(&itemptr, iprop);
4954 RAW_SET(bool, in, a, b);
4955 break;
4956 }
4957 case PROP_INT: {
4958 int i = RNA_property_int_get(&itemptr, iprop);
4959 RAW_SET(int, in, a, i);
4960 break;
4961 }
4962 case PROP_FLOAT: {
4963 float f = RNA_property_float_get(&itemptr, iprop);
4964 RAW_SET(float, in, a, f);
4965 break;
4966 }
4967 case PROP_ENUM: {
4968 int i = RNA_property_enum_get(&itemptr, iprop);
4969 RAW_SET(int, in, a, i);
4970 break;
4971 }
4972 default:
4974 break;
4975 }
4976 }
4977 a++;
4978 }
4979 else if (needconv == 1) {
4980 /* allocate temporary array if needed */
4981 if (tmparray && tmplen != itemlen) {
4982 MEM_freeN(tmparray);
4983 tmparray = nullptr;
4984 }
4985 if (!tmparray) {
4986 tmparray = MEM_callocN(sizeof(float) * itemlen, "RNA tmparray");
4987 tmplen = itemlen;
4988 }
4989
4990 /* handle conversions */
4991 if (set) {
4992 switch (itemtype) {
4993 case PROP_BOOLEAN: {
4994 bool *array = static_cast<bool *>(tmparray);
4995 for (j = 0; j < itemlen; j++, a++) {
4996 RAW_GET(bool, array[j], in, a);
4997 }
4998 RNA_property_boolean_set_array(&itemptr, iprop, array);
4999 break;
5000 }
5001 case PROP_INT: {
5002 int *array = static_cast<int *>(tmparray);
5003 for (j = 0; j < itemlen; j++, a++) {
5004 RAW_GET(int, array[j], in, a);
5005 }
5006 RNA_property_int_set_array(&itemptr, iprop, array);
5007 break;
5008 }
5009 case PROP_FLOAT: {
5010 float *array = static_cast<float *>(tmparray);
5011 for (j = 0; j < itemlen; j++, a++) {
5012 RAW_GET(float, array[j], in, a);
5013 }
5014 RNA_property_float_set_array(&itemptr, iprop, array);
5015 break;
5016 }
5017 default:
5019 break;
5020 }
5021 }
5022 else {
5023 switch (itemtype) {
5024 case PROP_BOOLEAN: {
5025 bool *array = static_cast<bool *>(tmparray);
5026 RNA_property_boolean_get_array(&itemptr, iprop, array);
5027 for (j = 0; j < itemlen; j++, a++) {
5028 RAW_SET(int, in, a, ((bool *)tmparray)[j]);
5029 }
5030 break;
5031 }
5032 case PROP_INT: {
5033 int *array = static_cast<int *>(tmparray);
5034 RNA_property_int_get_array(&itemptr, iprop, array);
5035 for (j = 0; j < itemlen; j++, a++) {
5036 RAW_SET(int, in, a, array[j]);
5037 }
5038 break;
5039 }
5040 case PROP_FLOAT: {
5041 float *array = static_cast<float *>(tmparray);
5042 RNA_property_float_get_array(&itemptr, iprop, array);
5043 for (j = 0; j < itemlen; j++, a++) {
5044 RAW_SET(float, in, a, array[j]);
5045 }
5046 break;
5047 }
5048 default:
5050 break;
5051 }
5052 }
5053 }
5054 else {
5055 if (set) {
5056 switch (itemtype) {
5057 case PROP_BOOLEAN: {
5058 RNA_property_boolean_set_array(&itemptr, iprop, &((bool *)in.array)[a]);
5059 a += itemlen;
5060 break;
5061 }
5062 case PROP_INT: {
5063 RNA_property_int_set_array(&itemptr, iprop, &((int *)in.array)[a]);
5064 a += itemlen;
5065 break;
5066 }
5067 case PROP_FLOAT: {
5068 RNA_property_float_set_array(&itemptr, iprop, &((float *)in.array)[a]);
5069 a += itemlen;
5070 break;
5071 }
5072 default:
5074 break;
5075 }
5076 }
5077 else {
5078 switch (itemtype) {
5079 case PROP_BOOLEAN: {
5080 RNA_property_boolean_get_array(&itemptr, iprop, &((bool *)in.array)[a]);
5081 a += itemlen;
5082 break;
5083 }
5084 case PROP_INT: {
5085 RNA_property_int_get_array(&itemptr, iprop, &((int *)in.array)[a]);
5086 a += itemlen;
5087 break;
5088 }
5089 case PROP_FLOAT: {
5090 RNA_property_float_get_array(&itemptr, iprop, &((float *)in.array)[a]);
5091 a += itemlen;
5092 break;
5093 }
5094 default:
5096 break;
5097 }
5098 }
5099 }
5100 }
5101 }
5102 }
5104
5105 if (tmparray) {
5106 MEM_freeN(tmparray);
5107 }
5108
5109 return !err;
5110 }
5111}
5112
5114{
5115 if (prop->rawtype == PROP_RAW_UNSET) {
5116 /* this property has no raw access,
5117 * yet we try to provide a raw type to help building the array. */
5118 switch (prop->type) {
5119 case PROP_BOOLEAN:
5120 return PROP_RAW_BOOLEAN;
5121 case PROP_INT:
5122 return PROP_RAW_INT;
5123 case PROP_FLOAT:
5124 return PROP_RAW_FLOAT;
5125 case PROP_ENUM:
5126 return PROP_RAW_INT;
5127 default:
5128 break;
5129 }
5130 }
5131 return prop->rawtype;
5132}
5133
5135 PointerRNA *ptr,
5136 PropertyRNA *prop,
5137 const char *propname,
5138 void *array,
5139 RawPropertyType type,
5140 int len)
5141{
5142 return rna_raw_access(reports, ptr, prop, propname, array, type, len, 0);
5143}
5144
5146 PointerRNA *ptr,
5147 PropertyRNA *prop,
5148 const char *propname,
5149 void *array,
5150 RawPropertyType type,
5151 int len)
5152{
5153 return rna_raw_access(reports, ptr, prop, propname, array, type, len, 1);
5154}
5155
5156/* Standard iterator functions */
5157
5159 ListBase *lb,
5160 IteratorSkipFunc skip)
5161{
5162 ListBaseIterator *internal = &iter->internal.listbase;
5163
5164 internal->link = (lb) ? static_cast<Link *>(lb->first) : nullptr;
5165 internal->skip = skip;
5166
5167 iter->valid = (internal->link != nullptr);
5168
5169 if (skip && iter->valid && skip(iter, internal->link)) {
5171 }
5172}
5173
5175{
5176 ListBaseIterator *internal = &iter->internal.listbase;
5177
5178 if (internal->skip) {
5179 do {
5180 internal->link = internal->link->next;
5181 iter->valid = (internal->link != nullptr);
5182 } while (iter->valid && internal->skip(iter, internal->link));
5183 }
5184 else {
5185 internal->link = internal->link->next;
5186 iter->valid = (internal->link != nullptr);
5187 }
5188}
5189
5191{
5192 ListBaseIterator *internal = &iter->internal.listbase;
5193
5194 return internal->link;
5195}
5196
5198
5200{
5201 void *data = BLI_findlink(lb, index);
5202 return rna_pointer_inherit_refine(ptr, type, data);
5203}
5204
5206 void *ptr,
5207 int itemsize,
5208 int length,
5209 bool free_ptr,
5210 IteratorSkipFunc skip)
5211{
5212 ArrayIterator *internal;
5213
5214 if (ptr == nullptr) {
5215 length = 0;
5216 }
5217 else if (length == 0) {
5218 ptr = nullptr;
5219 itemsize = 0;
5220 }
5221
5222 internal = &iter->internal.array;
5223 internal->ptr = static_cast<char *>(ptr);
5224 internal->free_ptr = free_ptr ? ptr : nullptr;
5225 internal->endptr = ((char *)ptr) + length * itemsize;
5226 internal->itemsize = itemsize;
5227 internal->skip = skip;
5228 internal->length = length;
5229
5230 iter->valid = (internal->ptr != internal->endptr);
5231
5232 if (skip && iter->valid && skip(iter, internal->ptr)) {
5234 }
5235}
5236
5238{
5239 ArrayIterator *internal = &iter->internal.array;
5240
5241 if (internal->skip) {
5242 do {
5243 internal->ptr += internal->itemsize;
5244 iter->valid = (internal->ptr != internal->endptr);
5245 } while (iter->valid && internal->skip(iter, internal->ptr));
5246 }
5247 else {
5248 internal->ptr += internal->itemsize;
5249 iter->valid = (internal->ptr != internal->endptr);
5250 }
5251}
5252
5254{
5255 ArrayIterator *internal = &iter->internal.array;
5256
5257 return internal->ptr;
5258}
5259
5261{
5262 ArrayIterator *internal = &iter->internal.array;
5263
5264 /* for ** arrays */
5265 return *(void **)(internal->ptr);
5266}
5267
5269{
5270 ArrayIterator *internal = &iter->internal.array;
5271
5272 MEM_SAFE_FREE(internal->free_ptr);
5273}
5274
5276 PointerRNA *ptr, StructRNA *type, void *data, int itemsize, int length, int index)
5277{
5278 if (index < 0 || index >= length) {
5279 return PointerRNA_NULL;
5280 }
5281
5282 return rna_pointer_inherit_refine(ptr, type, ((char *)data) + index * itemsize);
5283}
5284
5285/* Quick name based property access */
5286
5287bool RNA_boolean_get(PointerRNA *ptr, const char *name)
5288{
5290
5291 if (prop) {
5292 return RNA_property_boolean_get(ptr, prop);
5293 }
5294 printf("%s: %s.%s not found.\n", __func__, ptr->type->identifier, name);
5295 return false;
5296}
5297
5298void RNA_boolean_set(PointerRNA *ptr, const char *name, bool value)
5299{
5301
5302 if (prop) {
5303 RNA_property_boolean_set(ptr, prop, value);
5304 }
5305 else {
5306 printf("%s: %s.%s not found.\n", __func__, ptr->type->identifier, name);
5307 }
5308}
5309
5310void RNA_boolean_get_array(PointerRNA *ptr, const char *name, bool *values)
5311{
5313
5314 if (prop) {
5315 RNA_property_boolean_get_array(ptr, prop, values);
5316 }
5317 else {
5318 printf("%s: %s.%s not found.\n", __func__, ptr->type->identifier, name);
5319 }
5320}
5321
5322void RNA_boolean_set_array(PointerRNA *ptr, const char *name, const bool *values)
5323{
5325
5326 if (prop) {
5327 RNA_property_boolean_set_array(ptr, prop, values);
5328 }
5329 else {
5330 printf("%s: %s.%s not found.\n", __func__, ptr->type->identifier, name);
5331 }
5332}
5333
5334int RNA_int_get(PointerRNA *ptr, const char *name)
5335{
5337
5338 if (prop) {
5339 return RNA_property_int_get(ptr, prop);
5340 }
5341 printf("%s: %s.%s not found.\n", __func__, ptr->type->identifier, name);
5342 return 0;
5343}
5344
5345void RNA_int_set(PointerRNA *ptr, const char *name, int value)
5346{
5348
5349 if (prop) {
5350 RNA_property_int_set(ptr, prop, value);
5351 }
5352 else {
5353 printf("%s: %s.%s not found.\n", __func__, ptr->type->identifier, name);
5354 }
5355}
5356
5357void RNA_int_get_array(PointerRNA *ptr, const char *name, int *values)
5358{
5360
5361 if (prop) {
5362 RNA_property_int_get_array(ptr, prop, values);
5363 }
5364 else {
5365 printf("%s: %s.%s not found.\n", __func__, ptr->type->identifier, name);
5366 }
5367}
5368
5369void RNA_int_set_array(PointerRNA *ptr, const char *name, const int *values)
5370{
5372
5373 if (prop) {
5374 RNA_property_int_set_array(ptr, prop, values);
5375 }
5376 else {
5377 printf("%s: %s.%s not found.\n", __func__, ptr->type->identifier, name);
5378 }
5379}
5380
5381float RNA_float_get(PointerRNA *ptr, const char *name)
5382{
5384
5385 if (prop) {
5386 return RNA_property_float_get(ptr, prop);
5387 }
5388 printf("%s: %s.%s not found.\n", __func__, ptr->type->identifier, name);
5389 return 0;
5390}
5391
5392void RNA_float_set(PointerRNA *ptr, const char *name, float value)
5393{
5395
5396 if (prop) {
5397 RNA_property_float_set(ptr, prop, value);
5398 }
5399 else {
5400 printf("%s: %s.%s not found.\n", __func__, ptr->type->identifier, name);
5401 }
5402}
5403
5404void RNA_float_get_array(PointerRNA *ptr, const char *name, float *values)
5405{
5407
5408 if (prop) {
5409 RNA_property_float_get_array(ptr, prop, values);
5410 }
5411 else {
5412 printf("%s: %s.%s not found.\n", __func__, ptr->type->identifier, name);
5413 }
5414}
5415
5416void RNA_float_set_array(PointerRNA *ptr, const char *name, const float *values)
5417{
5419
5420 if (prop) {
5421 RNA_property_float_set_array(ptr, prop, values);
5422 }
5423 else {
5424 printf("%s: %s.%s not found.\n", __func__, ptr->type->identifier, name);
5425 }
5426}
5427
5428int RNA_enum_get(PointerRNA *ptr, const char *name)
5429{
5431
5432 if (prop) {
5433 return RNA_property_enum_get(ptr, prop);
5434 }
5435 printf("%s: %s.%s not found.\n", __func__, ptr->type->identifier, name);
5436 return 0;
5437}
5438
5439void RNA_enum_set(PointerRNA *ptr, const char *name, int value)
5440{
5442
5443 if (prop) {
5444 RNA_property_enum_set(ptr, prop, value);
5445 }
5446 else {
5447 printf("%s: %s.%s not found.\n", __func__, ptr->type->identifier, name);
5448 }
5449}
5450
5451void RNA_enum_set_identifier(bContext *C, PointerRNA *ptr, const char *name, const char *id)
5452{
5454
5455 if (prop) {
5456 int value;
5457 if (RNA_property_enum_value(C, ptr, prop, id, &value)) {
5458 RNA_property_enum_set(ptr, prop, value);
5459 }
5460 else {
5461 printf("%s: %s.%s has no enum id '%s'.\n", __func__, ptr->type->identifier, name, id);
5462 }
5463 }
5464 else {
5465 printf("%s: %s.%s not found.\n", __func__, ptr->type->identifier, name);
5466 }
5467}
5468
5469bool RNA_enum_is_equal(bContext *C, PointerRNA *ptr, const char *name, const char *enumname)
5470{
5472 const EnumPropertyItem *item;
5473 bool free;
5474
5475 if (prop) {
5476 int i;
5477 bool cmp = false;
5478
5479 RNA_property_enum_items(C, ptr, prop, &item, nullptr, &free);
5480 i = RNA_enum_from_identifier(item, enumname);
5481 if (i != -1) {
5482 cmp = (item[i].value == RNA_property_enum_get(ptr, prop));
5483 }
5484
5485 if (free) {
5486 MEM_freeN((void *)item);
5487 }
5488
5489 if (i != -1) {
5490 return cmp;
5491 }
5492
5493 printf("%s: %s.%s item %s not found.\n", __func__, ptr->type->identifier, name, enumname);
5494 return false;
5495 }
5496 printf("%s: %s.%s not found.\n", __func__, ptr->type->identifier, name);
5497 return false;
5498}
5499
5500bool RNA_enum_value_from_id(const EnumPropertyItem *item, const char *identifier, int *r_value)
5501{
5502 const int i = RNA_enum_from_identifier(item, identifier);
5503 if (i != -1) {
5504 *r_value = item[i].value;
5505 return true;
5506 }
5507 return false;
5508}
5509
5510bool RNA_enum_id_from_value(const EnumPropertyItem *item, int value, const char **r_identifier)
5511{
5512 const int i = RNA_enum_from_value(item, value);
5513 if (i != -1) {
5514 *r_identifier = item[i].identifier;
5515 return true;
5516 }
5517 return false;
5518}
5519
5520bool RNA_enum_icon_from_value(const EnumPropertyItem *item, int value, int *r_icon)
5521{
5522 const int i = RNA_enum_from_value(item, value);
5523 if (i != -1) {
5524 *r_icon = item[i].icon;
5525 return true;
5526 }
5527 return false;
5528}
5529
5530bool RNA_enum_name_from_value(const EnumPropertyItem *item, int value, const char **r_name)
5531{
5532 const int i = RNA_enum_from_value(item, value);
5533 if (i != -1) {
5534 *r_name = item[i].name;
5535 return true;
5536 }
5537 return false;
5538}
5539
5540void RNA_string_get(PointerRNA *ptr, const char *name, char *value)
5541{
5543
5544 if (prop) {
5545 RNA_property_string_get(ptr, prop, value);
5546 }
5547 else {
5548 printf("%s: %s.%s not found.\n", __func__, ptr->type->identifier, name);
5549 value[0] = '\0';
5550 }
5551}
5552
5554 PointerRNA *ptr, const char *name, char *fixedbuf, int fixedlen, int *r_len)
5555{
5557
5558 if (prop) {
5559 return RNA_property_string_get_alloc(ptr, prop, fixedbuf, fixedlen, r_len);
5560 }
5561 printf("%s: %s.%s not found.\n", __func__, ptr->type->identifier, name);
5562 if (r_len != nullptr) {
5563 *r_len = 0;
5564 }
5565 return nullptr;
5566}
5567
5568int RNA_string_length(PointerRNA *ptr, const char *name)
5569{
5571
5572 if (prop) {
5573 return RNA_property_string_length(ptr, prop);
5574 }
5575 printf("%s: %s.%s not found.\n", __func__, ptr->type->identifier, name);
5576 return 0;
5577}
5578
5579void RNA_string_set(PointerRNA *ptr, const char *name, const char *value)
5580{
5582
5583 if (prop) {
5584 RNA_property_string_set(ptr, prop, value);
5585 }
5586 else {
5587 printf("%s: %s.%s not found.\n", __func__, ptr->type->identifier, name);
5588 }
5589}
5590
5592{
5594
5595 if (prop) {
5596 return RNA_property_pointer_get(ptr, prop);
5597 }
5598 printf("%s: %s.%s not found.\n", __func__, ptr->type->identifier, name);
5599
5600 return PointerRNA_NULL;
5601}
5602
5603void RNA_pointer_set(PointerRNA *ptr, const char *name, PointerRNA ptr_value)
5604{
5606
5607 if (prop) {
5608 RNA_property_pointer_set(ptr, prop, ptr_value, nullptr);
5609 }
5610 else {
5611 printf("%s: %s.%s not found.\n", __func__, ptr->type->identifier, name);
5612 }
5613}
5614
5615void RNA_pointer_add(PointerRNA *ptr, const char *name)
5616{
5618
5619 if (prop) {
5621 }
5622 else {
5623 printf("%s: %s.%s not found.\n", __func__, ptr->type->identifier, name);
5624 }
5625}
5626
5628{
5630
5631 if (prop) {
5633 }
5634 else {
5635 printf("%s: %s.%s not found.\n", __func__, ptr->type->identifier, name);
5636 }
5637}
5638
5639void RNA_collection_add(PointerRNA *ptr, const char *name, PointerRNA *r_value)
5640{
5642
5643 if (prop) {
5644 RNA_property_collection_add(ptr, prop, r_value);
5645 }
5646 else {
5647 printf("%s: %s.%s not found.\n", __func__, ptr->type->identifier, name);
5648 }
5649}
5650
5651void RNA_collection_clear(PointerRNA *ptr, const char *name)
5652{
5654
5655 if (prop) {
5657 }
5658 else {
5659 printf("%s: %s.%s not found.\n", __func__, ptr->type->identifier, name);
5660 }
5661}
5662
5663int RNA_collection_length(PointerRNA *ptr, const char *name)
5664{
5666
5667 if (prop) {
5668 return RNA_property_collection_length(ptr, prop);
5669 }
5670 printf("%s: %s.%s not found.\n", __func__, ptr->type->identifier, name);
5671 return 0;
5672}
5673
5675{
5677
5678 if (prop) {
5680 }
5681 printf("%s: %s.%s not found.\n", __func__, ptr->type->identifier, name);
5682 return false;
5683}
5684
5686{
5687 prop = rna_ensure_property(prop);
5688 if (prop->flag & PROP_IDPROPERTY) {
5689 IDProperty *idprop = rna_idproperty_find(ptr, prop->identifier);
5690 return ((idprop != nullptr) && (use_ghost == false || !(idprop->flag & IDP_FLAG_GHOST)));
5691 }
5692 return true;
5693}
5694
5696{
5697 prop = rna_ensure_property(prop);
5698 if (prop->flag & PROP_IDPROPERTY) {
5699 IDProperty *idprop = rna_idproperty_find(ptr, prop->identifier);
5700 return ((idprop != nullptr) && !(idprop->flag & IDP_FLAG_GHOST));
5701 }
5702 return true;
5703}
5704
5706{
5707 prop = rna_ensure_property(prop);
5708 if (prop->flag & PROP_IDPROPERTY) {
5710 }
5711}
5712
5713bool RNA_struct_property_is_set_ex(PointerRNA *ptr, const char *identifier, bool use_ghost)
5714{
5715 PropertyRNA *prop = RNA_struct_find_property(ptr, identifier);
5716
5717 if (prop) {
5718 return RNA_property_is_set_ex(ptr, prop, use_ghost);
5719 }
5720 /* python raises an error */
5721 // printf("%s: %s.%s not found.\n", __func__, ptr->type->identifier, name);
5722 return false;
5723}
5724
5725bool RNA_struct_property_is_set(PointerRNA *ptr, const char *identifier)
5726{
5727 PropertyRNA *prop = RNA_struct_find_property(ptr, identifier);
5728
5729 if (prop) {
5730 return RNA_property_is_set(ptr, prop);
5731 }
5732 /* python raises an error */
5733 // printf("%s: %s.%s not found.\n", __func__, ptr->type->identifier, name);
5734 return false;
5735}
5736
5737void RNA_struct_property_unset(PointerRNA *ptr, const char *identifier)
5738{
5739 PropertyRNA *prop = RNA_struct_find_property(ptr, identifier);
5740
5741 if (prop) {
5742 RNA_property_unset(ptr, prop);
5743 }
5744}
5745
5747{
5748 return (prop->magic != RNA_MAGIC);
5749}
5750
5752{
5753 const int flag = RNA_property_flag(prop);
5754 if (RNA_property_type(prop) == PROP_STRING) {
5755 return (flag & PROP_NEVER_UNLINK) == 0;
5756 }
5757 return (flag & (PROP_NEVER_UNLINK | PROP_NEVER_NULL)) == 0;
5758}
5759
5761{
5762 std::stringstream ss;
5763
5764 const char *propname;
5765 int first_time = 1;
5766
5767 ss << '{';
5768
5769 RNA_STRUCT_BEGIN (ptr, prop) {
5770 propname = RNA_property_identifier(prop);
5771
5772 if (STREQ(propname, "rna_type")) {
5773 continue;
5774 }
5775
5776 if (first_time == 0) {
5777 ss << ", ";
5778 }
5779 first_time = 0;
5780
5781 const std::string str = RNA_property_as_string(C, ptr, prop, -1, INT_MAX);
5782 ss << fmt::format("\"{}\":{}", propname, str);
5783 }
5785
5786 ss << '}';
5787
5788 return ss.str();
5789}
5790
5791static std::optional<std::string> rna_pointer_as_string__bldata(PointerRNA *ptr)
5792{
5793 if (ptr->type == nullptr || ptr->owner_id == nullptr) {
5794 return "None";
5795 }
5796 if (RNA_struct_is_ID(ptr->type)) {
5798 }
5800}
5801
5802std::optional<std::string> RNA_pointer_as_string(bContext *C,
5803 PointerRNA *ptr,
5804 PropertyRNA *prop_ptr,
5805 PointerRNA *ptr_prop)
5806{
5807 IDProperty *prop;
5808 if (ptr_prop->data == nullptr) {
5809 return "None";
5810 }
5811 if ((prop = rna_idproperty_check(&prop_ptr, ptr)) && prop->type != IDP_ID) {
5812 return RNA_pointer_as_string_id(C, ptr_prop);
5813 }
5814 return rna_pointer_as_string__bldata(ptr_prop);
5815}
5816
5818 PointerRNA *ptr,
5819 const bool as_function,
5820 const bool all_args,
5821 const bool nested_args,
5822 const int max_prop_length,
5823 PropertyRNA *iterprop)
5824{
5825 const char *arg_name = nullptr;
5826
5827 PropertyRNA *prop;
5828
5829 std::stringstream ss;
5830
5831 bool first_iter = true;
5832 int flag, flag_parameter;
5833
5834 RNA_PROP_BEGIN (ptr, propptr, iterprop) {
5835 prop = static_cast<PropertyRNA *>(propptr.data);
5836
5837 flag = RNA_property_flag(prop);
5838 flag_parameter = RNA_parameter_flag(prop);
5839
5840 if (as_function && (flag_parameter & PARM_OUTPUT)) {
5841 continue;
5842 }
5843
5844 arg_name = RNA_property_identifier(prop);
5845
5846 if (STREQ(arg_name, "rna_type")) {
5847 continue;
5848 }
5849
5850 if ((nested_args == false) && (RNA_property_type(prop) == PROP_POINTER)) {
5851 continue;
5852 }
5853
5854 if (as_function && (prop->flag_parameter & PARM_REQUIRED)) {
5855 /* required args don't have useful defaults */
5856 ss << fmt::format(first_iter ? "{}" : ", {}", arg_name);
5857 first_iter = false;
5858 }
5859 else {
5860 bool ok = true;
5861
5862 if (all_args == true) {
5863 /* pass */
5864 }
5865 else if (RNA_struct_idprops_check(ptr->type)) {
5866 ok = RNA_property_is_set(ptr, prop);
5867 }
5868
5869 if (ok) {
5870 std::string buf;
5871 if (as_function && RNA_property_type(prop) == PROP_POINTER) {
5872 /* don't expand pointers for functions */
5873 if (flag & PROP_NEVER_NULL) {
5874 /* we can't really do the right thing here. arg=arg?, hrmf! */
5875 buf = arg_name;
5876 }
5877 else {
5878 buf = "None";
5879 }
5880 }
5881 else {
5882 buf = RNA_property_as_string(C, ptr, prop, -1, max_prop_length);
5883 }
5884
5885 ss << fmt::format(first_iter ? "{}={}" : ", {}={}", arg_name, buf);
5886 first_iter = false;
5887 }
5888 }
5889 }
5891
5892 return ss.str();
5893}
5894
5896 PointerRNA *ptr,
5897 const bool as_function,
5898 const bool all_args,
5899 const bool nested_args,
5900 const int max_prop_length)
5901{
5902 PropertyRNA *iterprop;
5903
5905
5907 C, ptr, as_function, all_args, nested_args, max_prop_length, iterprop);
5908}
5909
5911 FunctionRNA *func,
5912 const bool as_function,
5913 const bool all_args,
5914 const int max_prop_length)
5915{
5916 PointerRNA funcptr = RNA_pointer_create(nullptr, &RNA_Function, func);
5917
5918 PropertyRNA *iterprop = RNA_struct_find_property(&funcptr, "parameters");
5919
5921
5923 C, &funcptr, as_function, all_args, true, max_prop_length, iterprop);
5924}
5925
5926static const char *bool_as_py_string(const int var)
5927{
5928 return var ? "True" : "False";
5929}
5930
5932 int type, int len, PointerRNA *ptr, PropertyRNA *prop, void **r_buf_end)
5933{
5934 switch (type) {
5935 case PROP_BOOLEAN: {
5936 bool *buf = static_cast<bool *>(MEM_mallocN(sizeof(*buf) * len, __func__));
5938 *r_buf_end = buf + len;
5939 return buf;
5940 }
5941 case PROP_INT: {
5942 int *buf = static_cast<int *>(MEM_mallocN(sizeof(*buf) * len, __func__));
5943 RNA_property_int_get_array(ptr, prop, buf);
5944 *r_buf_end = buf + len;
5945 return buf;
5946 }
5947 case PROP_FLOAT: {
5948 float *buf = static_cast<float *>(MEM_mallocN(sizeof(*buf) * len, __func__));
5950 *r_buf_end = buf + len;
5951 return buf;
5952 }
5953 default:
5955 return nullptr;
5956 }
5957}
5958
5959static void rna_array_as_string_elem(int type, void **buf_p, int len, std::stringstream &ss)
5960{
5961 /* This will print a comma separated string of the array elements from
5962 * buf start to len. We will add a comma if len == 1 to preserve tuples. */
5963 const int end = len - 1;
5964 switch (type) {
5965 case PROP_BOOLEAN: {
5966 bool *buf = static_cast<bool *>(*buf_p);
5967 for (int i = 0; i < len; i++, buf++) {
5968 ss << fmt::format((i < end || !end) ? "{}, " : "{}", bool_as_py_string(*buf));
5969 }
5970 *buf_p = buf;
5971 break;
5972 }
5973 case PROP_INT: {
5974 int *buf = static_cast<int *>(*buf_p);
5975 for (int i = 0; i < len; i++, buf++) {
5976 ss << fmt::format((i < end || !end) ? "{}, " : "{}", *buf);
5977 }
5978 *buf_p = buf;
5979 break;
5980 }
5981 case PROP_FLOAT: {
5982 float *buf = static_cast<float *>(*buf_p);
5983 for (int i = 0; i < len; i++, buf++) {
5984 ss << fmt::format((i < end || !end) ? "{:g}, " : "{:g}", *buf);
5985 }
5986 *buf_p = buf;
5987 break;
5988 }
5989 default:
5991 }
5992}
5993
5995 int type, void **buf_p, int totdim, const int *dim_size, std::stringstream &ss)
5996{
5997 ss << '(';
5998 if (totdim > 1) {
5999 totdim--;
6000 const int end = dim_size[totdim] - 1;
6001 for (int i = 0; i <= end; i++) {
6002 rna_array_as_string_recursive(type, buf_p, totdim, dim_size, ss);
6003 if (i < end || !end) {
6004 ss << ", ";
6005 }
6006 }
6007 }
6008 else {
6009 rna_array_as_string_elem(type, buf_p, dim_size[0], ss);
6010 }
6011 ss << ')';
6012}
6013
6015 int type, int len, PointerRNA *ptr, PropertyRNA *prop, std::stringstream &ss)
6016{
6017 void *buf_end;
6018 void *buf = rna_array_as_string_alloc(type, len, ptr, prop, &buf_end);
6019 void *buf_step = buf;
6020 int totdim, dim_size[RNA_MAX_ARRAY_DIMENSION];
6021
6022 totdim = RNA_property_array_dimension(ptr, prop, dim_size);
6023
6024 rna_array_as_string_recursive(type, &buf_step, totdim, dim_size, ss);
6025 BLI_assert(buf_step == buf_end);
6026 MEM_freeN(buf);
6027}
6028
6030 bContext *C, PointerRNA *ptr, PropertyRNA *prop, int index, int max_prop_length)
6031{
6032 int type = RNA_property_type(prop);
6033 int len = RNA_property_array_length(ptr, prop);
6034
6035 std::stringstream ss;
6036
6037 /* see if we can coerce into a python type - PropertyType */
6038 switch (type) {
6039 case PROP_BOOLEAN:
6040 if (len == 0) {
6042 }
6043 else {
6044 if (index != -1) {
6046 }
6047 else {
6048 rna_array_as_string(type, len, ptr, prop, ss);
6049 }
6050 }
6051 break;
6052 case PROP_INT:
6053 if (len == 0) {
6054 ss << RNA_property_int_get(ptr, prop);
6055 }
6056 else {
6057 if (index != -1) {
6058 ss << RNA_property_int_get_index(ptr, prop, index);
6059 }
6060 else {
6061 rna_array_as_string(type, len, ptr, prop, ss);
6062 }
6063 }
6064 break;
6065 case PROP_FLOAT:
6066 if (len == 0) {
6067 ss << fmt::format("{:g}", RNA_property_float_get(ptr, prop));
6068 }
6069 else {
6070 if (index != -1) {
6071 ss << fmt::format("{:g}", RNA_property_float_get_index(ptr, prop, index));
6072 }
6073 else {
6074 rna_array_as_string(type, len, ptr, prop, ss);
6075 }
6076 }
6077 break;
6078 case PROP_STRING: {
6079 char *buf_esc;
6080 char *buf;
6081 int length;
6082
6083 length = RNA_property_string_length(ptr, prop);
6084 buf = static_cast<char *>(
6085 MEM_mallocN(sizeof(char) * (length + 1), "RNA_property_as_string"));
6086 buf_esc = static_cast<char *>(
6087 MEM_mallocN(sizeof(char) * (length * 2 + 1), "RNA_property_as_string esc"));
6088 RNA_property_string_get(ptr, prop, buf);
6089 BLI_str_escape(buf_esc, buf, length * 2 + 1);
6090 MEM_freeN(buf);
6091 ss << fmt::format("\"{}\"", buf_esc);
6092 MEM_freeN(buf_esc);
6093 break;
6094 }
6095 case PROP_ENUM: {
6096 /* string arrays don't exist */
6097 const char *identifier;
6098 int val = RNA_property_enum_get(ptr, prop);
6099
6100 if (RNA_property_flag(prop) & PROP_ENUM_FLAG) {
6101 /* represent as a python set */
6102 if (val) {
6103 const EnumPropertyItem *item_array;
6104 bool free;
6105
6106 ss << "{";
6107
6108 RNA_property_enum_items(C, ptr, prop, &item_array, nullptr, &free);
6109 if (item_array) {
6110 const EnumPropertyItem *item = item_array;
6111 bool is_first = true;
6112 for (; item->identifier; item++) {
6113 if (item->identifier[0] && item->value & val) {
6114 ss << fmt::format(is_first ? "'{}'" : ", '{}'", item->identifier);
6115 is_first = false;
6116 }
6117 }
6118
6119 if (free) {
6120 MEM_freeN((void *)item_array);
6121 }
6122 }
6123
6124 ss << "}";
6125 }
6126 else {
6127 /* annoying exception, don't confuse with dictionary syntax above: {} */
6128 ss << "set()";
6129 }
6130 }
6131 else if (RNA_property_enum_identifier(C, ptr, prop, val, &identifier)) {
6132 ss << fmt::format("'{}'", identifier);
6133 }
6134 else {
6135 return "'<UNKNOWN ENUM>'";
6136 }
6137 break;
6138 }
6139 case PROP_POINTER: {
6141 ss << RNA_pointer_as_string(C, ptr, prop, &tptr).value_or("");
6142 break;
6143 }
6144 case PROP_COLLECTION: {
6145 int i = 0;
6146 CollectionPropertyIterator collect_iter;
6147 ss << "[";
6148
6149 for (RNA_property_collection_begin(ptr, prop, &collect_iter);
6150 (i < max_prop_length) && collect_iter.valid;
6151 RNA_property_collection_next(&collect_iter), i++)
6152 {
6153 PointerRNA itemptr = collect_iter.ptr;
6154
6155 if (i != 0) {
6156 ss << ", ";
6157 }
6158
6159 /* now get every prop of the collection */
6160 ss << RNA_pointer_as_string(C, ptr, prop, &itemptr).value_or("");
6161 }
6162
6163 RNA_property_collection_end(&collect_iter);
6164 ss << "]";
6165 break;
6166 }
6167 default:
6168 return "'<UNKNOWN TYPE>'"; /* TODO */
6169 }
6170
6171 return ss.str();
6172}
6173
6174/* Function */
6175
6177{
6178 return func->identifier;
6179}
6180
6182{
6183 return TIP_(func->description);
6184}
6185
6187{
6188 return func->description;
6189}
6190
6192{
6193 return func->flag;
6194}
6195
6197{
6198 return func->call != nullptr;
6199}
6200
6202{
6203 return static_cast<PropertyRNA *>(BLI_findlink(&func->cont.properties, index));
6204}
6205
6207 FunctionRNA *func,
6208 const char *identifier)
6209{
6210 PropertyRNA *parm;
6211
6212 parm = static_cast<PropertyRNA *>(func->cont.properties.first);
6213 for (; parm; parm = parm->next) {
6214 if (STREQ(RNA_property_identifier(parm), identifier)) {
6215 break;
6216 }
6217 }
6218
6219 return parm;
6220}
6221
6223{
6224 return &func->cont.properties;
6225}
6226
6227/* Utility */
6228
6230{
6231 return int(rna_ensure_property(prop)->flag_parameter);
6232}
6233
6235 PointerRNA * /*ptr*/,
6236 FunctionRNA *func)
6237{
6238 PointerRNA null_ptr = PointerRNA_NULL;
6239 void *data;
6240 int alloc_size = 0, size;
6241
6242 parms->arg_count = 0;
6243 parms->ret_count = 0;
6244
6245 /* allocate data */
6246 LISTBASE_FOREACH (PropertyRNA *, parm, &func->cont.properties) {
6247 alloc_size += rna_parameter_size_pad(rna_parameter_size(parm));
6248
6249 if (parm->flag_parameter & PARM_OUTPUT) {
6250 parms->ret_count++;
6251 }
6252 else {
6253 parms->arg_count++;
6254 }
6255 }
6256
6257 parms->data = MEM_callocN(alloc_size, "RNA_parameter_list_create");
6258 parms->func = func;
6259 parms->alloc_size = alloc_size;
6260
6261 /* set default values */
6262 data = parms->data;
6263
6264 LISTBASE_FOREACH (PropertyRNA *, parm, &func->cont.properties) {
6265 size = rna_parameter_size(parm);
6266
6267 /* set length to 0, these need to be set later, see bpy_array.c's py_to_array */
6268 if (parm->flag & PROP_DYNAMIC) {
6269 ParameterDynAlloc *data_alloc = static_cast<ParameterDynAlloc *>(data);
6270 data_alloc->array_tot = 0;
6271 data_alloc->array = nullptr;
6272 }
6273
6274 if (!(parm->flag_parameter & PARM_REQUIRED) && !(parm->flag & PROP_DYNAMIC)) {
6275 switch (parm->type) {
6276 case PROP_BOOLEAN:
6277 if (parm->arraydimension) {
6279 &null_ptr, (BoolPropertyRNA *)parm, static_cast<bool *>(data));
6280 }
6281 else {
6282 memcpy(data, &((BoolPropertyRNA *)parm)->defaultvalue, size);
6283 }
6284 break;
6285 case PROP_INT:
6286 if (parm->arraydimension) {
6288 &null_ptr, (IntPropertyRNA *)parm, static_cast<int *>(data));
6289 }
6290 else {
6291 memcpy(data, &((IntPropertyRNA *)parm)->defaultvalue, size);
6292 }
6293 break;
6294 case PROP_FLOAT:
6295 if (parm->arraydimension) {
6297 &null_ptr, (FloatPropertyRNA *)parm, static_cast<float *>(data));
6298 }
6299 else {
6300 memcpy(data, &((FloatPropertyRNA *)parm)->defaultvalue, size);
6301 }
6302 break;
6303 case PROP_ENUM:
6304 memcpy(data, &((EnumPropertyRNA *)parm)->defaultvalue, size);
6305 break;
6306 case PROP_STRING: {
6307 const char *defvalue = ((StringPropertyRNA *)parm)->defaultvalue;
6308 if (defvalue && defvalue[0]) {
6309 /* Causes bug #29988, possibly this is only correct for thick wrapped
6310 * need to look further into it - campbell */
6311#if 0
6312 BLI_strncpy(data, defvalue, size);
6313#else
6314 memcpy(data, &defvalue, size);
6315#endif
6316 }
6317 break;
6318 }
6319 case PROP_POINTER:
6320 case PROP_COLLECTION:
6321 break;
6322 }
6323 }
6324
6325 data = ((char *)data) + rna_parameter_size_pad(size);
6326 }
6327
6328 return parms;
6329}
6330
6332{
6333 PropertyRNA *parm;
6334 int tot;
6335
6336 parm = static_cast<PropertyRNA *>(parms->func->cont.properties.first);
6337 for (tot = 0; parm; parm = parm->next) {
6338 if (parm->type == PROP_COLLECTION) {
6339 BLI_freelistN((ListBase *)((char *)parms->data + tot));
6340 }
6341 else if (parm->flag & PROP_DYNAMIC) {
6342 /* for dynamic arrays and strings, data is a pointer to an array */
6343 ParameterDynAlloc *data_alloc = static_cast<ParameterDynAlloc *>(
6344 (void *)(((char *)parms->data) + tot));
6345 if (data_alloc->array) {
6346 MEM_freeN(data_alloc->array);
6347 }
6348 }
6349
6351 }
6352
6353 MEM_freeN(parms->data);
6354 parms->data = nullptr;
6355
6356 parms->func = nullptr;
6357}
6358
6360{
6361 return parms->alloc_size;
6362}
6363
6365{
6366 return parms->arg_count;
6367}
6368
6370{
6371 return parms->ret_count;
6372}
6373
6375{
6376 /* may be useful but unused now */
6377 // RNA_pointer_create(nullptr, &RNA_Function, parms->func, &iter->funcptr); /* UNUSED */
6378
6379 iter->parms = parms;
6380 iter->parm = static_cast<PropertyRNA *>(parms->func->cont.properties.first);
6381 iter->valid = iter->parm != nullptr;
6382 iter->offset = 0;
6383
6384 if (iter->valid) {
6385 iter->size = rna_parameter_size(iter->parm);
6386 iter->data = ((char *)iter->parms->data); /* +iter->offset, always 0 */
6387 }
6388}
6389
6391{
6392 iter->offset += rna_parameter_size_pad(iter->size);
6393 iter->parm = iter->parm->next;
6394 iter->valid = iter->parm != nullptr;
6395
6396 if (iter->valid) {
6397 iter->size = rna_parameter_size(iter->parm);
6398 iter->data = (((char *)iter->parms->data) + iter->offset);
6399 }
6400}
6401
6403{
6404 /* nothing to do */
6405}
6406
6407void RNA_parameter_get(ParameterList *parms, PropertyRNA *parm, void **r_value)
6408{
6409 ParameterIterator iter;
6410
6411 RNA_parameter_list_begin(parms, &iter);
6412
6413 for (; iter.valid; RNA_parameter_list_next(&iter)) {
6414 if (iter.parm == parm) {
6415 break;
6416 }
6417 }
6418
6419 if (iter.valid) {
6420 if (parm->flag & PROP_DYNAMIC) {
6421 /* for dynamic arrays and strings, data is a pointer to an array */
6422 ParameterDynAlloc *data_alloc = static_cast<ParameterDynAlloc *>(iter.data);
6423 *r_value = data_alloc->array;
6424 }
6425 else {
6426 *r_value = iter.data;
6427 }
6428 }
6429 else {
6430 *r_value = nullptr;
6431 }
6432
6434}
6435
6436void RNA_parameter_get_lookup(ParameterList *parms, const char *identifier, void **r_value)
6437{
6438 PropertyRNA *parm;
6439
6440 parm = static_cast<PropertyRNA *>(parms->func->cont.properties.first);
6441 for (; parm; parm = parm->next) {
6442 if (STREQ(RNA_property_identifier(parm), identifier)) {
6443 break;
6444 }
6445 }
6446
6447 if (parm) {
6448 RNA_parameter_get(parms, parm, r_value);
6449 }
6450}
6451
6452void RNA_parameter_set(ParameterList *parms, PropertyRNA *parm, const void *value)
6453{
6454 ParameterIterator iter;
6455
6456 RNA_parameter_list_begin(parms, &iter);
6457
6458 for (; iter.valid; RNA_parameter_list_next(&iter)) {
6459 if (iter.parm == parm) {
6460 break;
6461 }
6462 }
6463
6464 if (iter.valid) {
6465 if (parm->flag & PROP_DYNAMIC) {
6466 /* for dynamic arrays and strings, data is a pointer to an array */
6467 ParameterDynAlloc *data_alloc = static_cast<ParameterDynAlloc *>(iter.data);
6468 size_t size = 0;
6469 switch (parm->type) {
6470 case PROP_STRING:
6471 size = sizeof(char);
6472 break;
6473 case PROP_INT:
6474 case PROP_BOOLEAN:
6475 size = sizeof(int);
6476 break;
6477 case PROP_FLOAT:
6478 size = sizeof(float);
6479 break;
6480 default:
6481 break;
6482 }
6483 size *= data_alloc->array_tot;
6484 if (data_alloc->array) {
6485 MEM_freeN(data_alloc->array);
6486 }
6487 data_alloc->array = MEM_mallocN(size, __func__);
6488 memcpy(data_alloc->array, value, size);
6489 }
6490 else {
6491 memcpy(iter.data, value, iter.size);
6492 }
6493 }
6494
6496}
6497
6498void RNA_parameter_set_lookup(ParameterList *parms, const char *identifier, const void *value)
6499{
6500 PropertyRNA *parm;
6501
6502 parm = static_cast<PropertyRNA *>(parms->func->cont.properties.first);
6503 for (; parm; parm = parm->next) {
6504 if (STREQ(RNA_property_identifier(parm), identifier)) {
6505 break;
6506 }
6507 }
6508
6509 if (parm) {
6510 RNA_parameter_set(parms, parm, value);
6511 }
6512}
6513
6515{
6516 ParameterIterator iter;
6517 int len = 0;
6518
6519 RNA_parameter_list_begin(parms, &iter);
6520
6521 for (; iter.valid; RNA_parameter_list_next(&iter)) {
6522 if (iter.parm == parm) {
6523 break;
6524 }
6525 }
6526
6527 if (iter.valid) {
6528 len = RNA_parameter_dynamic_length_get_data(parms, parm, iter.data);
6529 }
6530
6532
6533 return len;
6534}
6535
6537{
6538 ParameterIterator iter;
6539
6540 RNA_parameter_list_begin(parms, &iter);
6541
6542 for (; iter.valid; RNA_parameter_list_next(&iter)) {
6543 if (iter.parm == parm) {
6544 break;
6545 }
6546 }
6547
6548 if (iter.valid) {
6549 RNA_parameter_dynamic_length_set_data(parms, parm, iter.data, length);
6550 }
6551
6553}
6554
6556{
6557 if (parm->flag & PROP_DYNAMIC) {
6558 return int(((ParameterDynAlloc *)data)->array_tot);
6559 }
6560 return 0;
6561}
6562
6564 PropertyRNA *parm,
6565 void *data,
6566 int length)
6567{
6568 if (parm->flag & PROP_DYNAMIC) {
6569 ((ParameterDynAlloc *)data)->array_tot = intptr_t(length);
6570 }
6571}
6572
6574 bContext *C, ReportList *reports, PointerRNA *ptr, FunctionRNA *func, ParameterList *parms)
6575{
6576 if (func->call) {
6577 func->call(C, reports, ptr, parms);
6578
6579 return 0;
6580 }
6581
6582 return -1;
6583}
6584
6586 const char *text, const char *text_ctxt, StructRNA *type, PropertyRNA *prop, int translate)
6587{
6588 return rna_translate_ui_text(text, text_ctxt, type, prop, translate);
6589}
6590
6592{
6593 int len;
6594
6595 /* get the length of the array to work with */
6597
6598 /* get and set the default values as appropriate for the various types */
6599 switch (RNA_property_type(prop)) {
6600 case PROP_BOOLEAN:
6601 if (len) {
6602 if (index == -1) {
6603 bool *tmparray = static_cast<bool *>(MEM_callocN(sizeof(bool) * len, __func__));
6604
6606 RNA_property_boolean_set_array(ptr, prop, tmparray);
6607
6608 MEM_freeN(tmparray);
6609 }
6610 else {
6611 int value = RNA_property_boolean_get_default_index(ptr, prop, index);
6612 RNA_property_boolean_set_index(ptr, prop, index, value);
6613 }
6614 }
6615 else {
6616 int value = RNA_property_boolean_get_default(ptr, prop);
6617 RNA_property_boolean_set(ptr, prop, value);
6618 }
6619 return true;
6620 case PROP_INT:
6621 if (len) {
6622 if (index == -1) {
6623 int *tmparray = static_cast<int *>(MEM_callocN(sizeof(int) * len, __func__));
6624
6625 RNA_property_int_get_default_array(ptr, prop, tmparray);
6626 RNA_property_int_set_array(ptr, prop, tmparray);
6627
6628 MEM_freeN(tmparray);
6629 }
6630 else {
6631 int value = RNA_property_int_get_default_index(ptr, prop, index);
6632 RNA_property_int_set_index(ptr, prop, index, value);
6633 }
6634 }
6635 else {
6636 int value = RNA_property_int_get_default(ptr, prop);
6637 RNA_property_int_set(ptr, prop, value);
6638 }
6639 return true;
6640 case PROP_FLOAT:
6641 if (len) {
6642 if (index == -1) {
6643 float *tmparray = static_cast<float *>(MEM_callocN(sizeof(float) * len, __func__));
6644
6646 RNA_property_float_set_array(ptr, prop, tmparray);
6647
6648 MEM_freeN(tmparray);
6649 }
6650 else {
6651 float value = RNA_property_float_get_default_index(ptr, prop, index);
6652 RNA_property_float_set_index(ptr, prop, index, value);
6653 }
6654 }
6655 else {
6656 float value = RNA_property_float_get_default(ptr, prop);
6657 RNA_property_float_set(ptr, prop, value);
6658 }
6659 return true;
6660 case PROP_ENUM: {
6661 int value = RNA_property_enum_get_default(ptr, prop);
6662 RNA_property_enum_set(ptr, prop, value);
6663 return true;
6664 }
6665
6666 case PROP_STRING: {
6667 char *value = RNA_property_string_get_default_alloc(ptr, prop, nullptr, 0, nullptr);
6668 RNA_property_string_set(ptr, prop, value);
6669 MEM_freeN(value);
6670 return true;
6671 }
6672
6673 case PROP_POINTER: {
6675 RNA_property_pointer_set(ptr, prop, value, nullptr);
6676 return true;
6677 }
6678
6679 default:
6680 /* FIXME: are there still any cases that haven't been handled?
6681 * comment out "default" block to check :) */
6682 return false;
6683 }
6684}
6685
6687{
6689 return false;
6690 }
6691
6692 /* get and set the default values as appropriate for the various types */
6693 switch (RNA_property_type(prop)) {
6694 case PROP_INT: {
6695 int value = RNA_property_int_get(ptr, prop);
6696 return RNA_property_int_set_default(prop, value);
6697 }
6698
6699 case PROP_FLOAT: {
6700 float value = RNA_property_float_get(ptr, prop);
6701 return RNA_property_float_set_default(prop, value);
6702 }
6703
6704 default:
6705 return false;
6706 }
6707}
6708
6709#ifdef WITH_PYTHON
6710extern void PyC_LineSpit(void);
6711#endif
6712
6713void _RNA_warning(const char *format, ...)
6714{
6715 va_list args;
6716
6717 va_start(args, format);
6718 vprintf(format, args);
6719 va_end(args);
6720
6721 /* gcc macro adds '\n', but can't use for other compilers */
6722#ifndef __GNUC__
6723 fputc('\n', stdout);
6724#endif
6725
6726#ifdef WITH_PYTHON
6727 {
6728 PyC_LineSpit();
6729 }
6730#endif
6731}
6732
6734 PropertyRNA *prop,
6735 const int prop_index,
6736 PathResolvedRNA *r_anim_rna)
6737{
6738 int array_len = RNA_property_array_length(ptr, prop);
6739
6740 if ((array_len == 0) || (prop_index < array_len)) {
6741 r_anim_rna->ptr = *ptr;
6742 r_anim_rna->prop = prop;
6743 r_anim_rna->prop_index = array_len ? prop_index : -1;
6744
6745 return true;
6746 }
6747 return false;
6748}
6749
6750static char rna_struct_state_owner[128];
6751void RNA_struct_state_owner_set(const char *name)
6752{
6753 if (name) {
6755 }
6756 else {
6757 rna_struct_state_owner[0] = '\0';
6758 }
6759}
6760
6762{
6763 if (rna_struct_state_owner[0]) {
6765 }
6766 return nullptr;
6767}
bool id_can_have_animdata(const ID *id)
Definition anim_data.cc:79
AnimData * BKE_animdata_from_id(const ID *id)
Definition anim_data.cc:89
Scene * CTX_data_scene(const bContext *C)
Main * CTX_data_main(const bContext *C)
wmMsgBus * CTX_wm_message_bus(const bContext *C)
FCurve * BKE_fcurve_find_by_rna(PointerRNA *ptr, PropertyRNA *prop, int rnaindex, AnimData **r_adt, bAction **r_action, bool *r_driven, bool *r_special)
#define G_MAIN
IDProperty * IDP_NewIDPArray(const char *name) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL()
Definition idprop.cc:69
#define IDP_Float(prop)
#define IDP_IDPArray(prop)
void IDP_FreeFromGroup(IDProperty *group, IDProperty *prop) ATTR_NONNULL()
Definition idprop.cc:757
#define IDP_Int(prop)
#define IDP_Id(prop)
#define IDP_Bool(prop)
eIDPropertyUIDataType IDP_ui_data_type(const IDProperty *prop)
Definition idprop.cc:1665
IDProperty * IDP_GetPropertyFromGroup(const IDProperty *prop, const char *name) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL()
Definition idprop.cc:763
void IDP_AssignStringMaxSize(IDProperty *prop, const char *st, size_t st_maxncpy) ATTR_NONNULL()
Definition idprop.cc:413
void IDP_ResizeIDPArray(IDProperty *prop, int len)
Definition idprop.cc:148
@ IDP_UI_DATA_TYPE_BOOLEAN
@ IDP_UI_DATA_TYPE_INT
IDProperty * IDP_GetIndexArray(IDProperty *prop, int index) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL()
Definition idprop.cc:133
void IDP_ReplaceInGroup_ex(IDProperty *group, IDProperty *prop, IDProperty *prop_exist)
Definition idprop.cc:654
#define IDP_String(prop)
IDProperty * IDP_New(char type, const IDPropertyTemplate *val, const char *name, eIDPropertyFlag flags={}) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL()
Definition idprop.cc:989
#define IDP_Double(prop)
bool IDP_AddToGroup(IDProperty *group, IDProperty *prop) ATTR_NONNULL()
Definition idprop.cc:722
void IDP_AppendArray(IDProperty *prop, IDProperty *item)
Definition idprop.cc:140
void IDP_AssignID(IDProperty *prop, ID *id, int flag)
Definition idprop.cc:538
void IDP_ResizeArray(IDProperty *prop, int newlen)
Definition idprop.cc:215
IDProperty * IDP_NewStringMaxSize(const char *st, size_t st_maxncpy, const char *name, eIDPropertyFlag flags={}) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(3)
Definition idprop.cc:357
IDPropertyUIData * IDP_ui_data_ensure(IDProperty *prop)
Definition idprop.cc:1739
void IDP_ReplaceInGroup(IDProperty *group, IDProperty *prop) ATTR_NONNULL()
Definition idprop.cc:669
#define IDP_Array(prop)
bool BKE_id_can_use_id(const ID &id_from, const ID &id_to)
Definition lib_id.cc:2461
bool BKE_lib_override_library_is_system_defined(const Main *bmain, const ID *id)
IDOverrideLibrary * BKE_lib_override_library_get(Main *bmain, ID *id, ID *owner_id_hint, ID **r_owner_id)
void BKE_reportf(ReportList *reports, eReportType type, const char *format,...) ATTR_PRINTF_FORMAT(3
void BKE_report(ReportList *reports, eReportType type, const char *message)
Definition report.cc:125
#define BLI_assert_unreachable()
Definition BLI_assert.h:97
#define BLI_assert(a)
Definition BLI_assert.h:50
#define BLI_assert_msg(a, msg)
Definition BLI_assert.h:57
A dynamically sized string ADT.
char * BLI_dynstr_get_cstring(const DynStr *ds) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT ATTR_NONNULL()
Definition BLI_dynstr.c:149
DynStr * BLI_dynstr_new(void) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT
Definition BLI_dynstr.c:37
void BLI_dynstr_free(DynStr *ds) ATTR_NONNULL()
Definition BLI_dynstr.c:174
void BLI_dynstr_appendf(DynStr *__restrict ds, const char *__restrict format,...) ATTR_PRINTF_FORMAT(2
void BLI_dynstr_append(DynStr *__restrict ds, const char *cstr) ATTR_NONNULL()
Definition BLI_dynstr.c:62
GHash * BLI_ghash_str_new(const char *info) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT
GHash * BLI_ghash_str_new_ex(const char *info, unsigned int nentries_reserve) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT
void * BLI_ghash_lookup(const GHash *gh, const void *key) ATTR_WARN_UNUSED_RESULT
Definition BLI_ghash.c:731
void BLI_ghash_insert(GHash *gh, void *key, void *val)
Definition BLI_ghash.c:707
void BLI_ghash_free(GHash *gh, GHashKeyFreeFP keyfreefp, GHashValFreeFP valfreefp)
Definition BLI_ghash.c:860
void BLI_kdtree_nd_ free(KDTree *tree)
#define LISTBASE_FOREACH(type, var, list)
void * BLI_findlink(const struct ListBase *listbase, int number) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
void void BLI_freelistN(struct ListBase *listbase) ATTR_NONNULL(1)
Definition listbase.cc:496
void * BLI_findstring_ptr(const struct ListBase *listbase, const char *id, int offset) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
MINLINE float max_ff(float a, float b)
MINLINE int min_ii(int a, int b)
MINLINE float min_ff(float a, float b)
MINLINE int max_ii(int a, int b)
MINLINE int mod_i(int i, int n)
#define STRNCPY(dst, src)
Definition BLI_string.h:593
#define BLI_string_debug_size(str, str_maxncpy)
Definition BLI_string.h:668
size_t BLI_str_escape(char *__restrict dst, const char *__restrict src, size_t dst_maxncpy) ATTR_NONNULL(1
char * BLI_strncpy(char *__restrict dst, const char *__restrict src, size_t dst_maxncpy) ATTR_NONNULL(1
unsigned int uint
#define BLI_MUTEX_INITIALIZER
Definition BLI_threads.h:84
void BLI_mutex_lock(ThreadMutex *mutex)
Definition threads.cc:345
void BLI_mutex_unlock(ThreadMutex *mutex)
Definition threads.cc:350
pthread_mutex_t ThreadMutex
Definition BLI_threads.h:83
#define UNUSED_VARS(...)
#define UNLIKELY(x)
#define ELEM(...)
#define STREQ(a, b)
bool BLT_translate_iface()
#define TIP_(msgid)
const char * BLT_pgettext(const char *msgctxt, const char *msgid)
#define CTX_IFACE_(context, msgid)
const char * BLT_translate_do_tooltip(const char *msgctxt, const char *msgid)
bool BLT_translate_tooltips()
const char * BLT_translate_do_iface(const char *msgctxt, const char *msgid)
typedef double(DMatrix)[4][4]
#define CLOG_WARN(clg_ref,...)
Definition CLG_log.h:181
void DEG_id_tag_update(ID *id, unsigned int flags)
void DEG_relations_tag_update(Main *bmain)
ID and Library types, which are fundamental for SDNA.
#define ID_TYPE_USE_COPY_ON_EVAL(_id_type)
Definition DNA_ID.h:693
@ ID_RECALC_PARAMETERS
Definition DNA_ID.h:1105
@ ID_RECALC_TRANSFORM
Definition DNA_ID.h:1021
@ ID_RECALC_SYNC_TO_EVAL
Definition DNA_ID.h:1085
@ ID_RECALC_GEOMETRY
Definition DNA_ID.h:1041
#define ID_IS_EDITABLE(_id)
Definition DNA_ID.h:658
@ ID_FLAG_EMBEDDED_DATA
Definition DNA_ID.h:725
#define ID_IS_OVERRIDE_LIBRARY(_id)
Definition DNA_ID.h:683
@ ID_NT
@ IDP_STRING_SUB_BYTE
@ IDP_DOUBLE
@ IDP_FLOAT
@ IDP_STRING
@ IDP_BOOLEAN
@ IDP_IDPARRAY
@ IDP_INT
@ IDP_GROUP
@ IDP_ARRAY
@ IDP_ID
@ IDP_FLAG_GHOST
@ IDP_FLAG_STATIC_TYPE
@ IDP_FLAG_OVERRIDELIBRARY_LOCAL
#define IDP_NUMTYPES
Object is a sort of wrapper for general info.
Read Guarded memory(de)allocation.
#define MEM_SAFE_FREE(v)
#define RNA_PROP_END
#define RNA_STRUCT_BEGIN(sptr, prop)
#define RNA_STRUCT_END
#define RNA_PROP_BEGIN(sptr, itemptr, prop)
StructRNA * ID_code_to_RNA_type(short idcode)
#define RNA_MAX_ARRAY_LENGTH
Definition RNA_define.hh:23
#define RNA_MAX_ARRAY_DIMENSION
Definition RNA_define.hh:26
@ PARM_REQUIRED
Definition RNA_types.hh:397
@ PARM_OUTPUT
Definition RNA_types.hh:398
bool(*)(CollectionPropertyIterator *iter, void *data) IteratorSkipFunc
Definition RNA_types.hh:413
PropertyScaleType
Definition RNA_types.hh:106
@ PROP_SCALE_LINEAR
Definition RNA_types.hh:108
@ STRUCT_NO_CONTEXT_WITHOUT_OWNER_ID
Definition RNA_types.hh:743
@ STRUCT_PUBLIC_NAMESPACE
Definition RNA_types.hh:735
@ STRUCT_ID
Definition RNA_types.hh:719
@ STRUCT_NO_DATABLOCK_IDPROPERTIES
Definition RNA_types.hh:731
@ STRUCT_CONTAINS_DATABLOCK_IDPROPERTIES
Definition RNA_types.hh:733
@ STRUCT_NO_IDPROPERTIES
Definition RNA_types.hh:729
@ STRUCT_UNDO
Definition RNA_types.hh:722
eStringPropertySearchFlag
Definition RNA_types.hh:570
@ PROP_STRING_SEARCH_SUPPORTED
Definition RNA_types.hh:575
PropertyType
Definition RNA_types.hh:64
@ PROP_FLOAT
Definition RNA_types.hh:67
@ PROP_BOOLEAN
Definition RNA_types.hh:65
@ PROP_ENUM
Definition RNA_types.hh:69
@ PROP_INT
Definition RNA_types.hh:66
@ PROP_STRING
Definition RNA_types.hh:68
@ PROP_POINTER
Definition RNA_types.hh:70
@ PROP_COLLECTION
Definition RNA_types.hh:71
bool(*)(Main *bmain, StructRNA *type) StructUnregisterFunc
Definition RNA_types.hh:760
PropertyUnit
Definition RNA_types.hh:75
StructRNA *(*)(Main *bmain, ReportList *reports, void *data, const char *identifier, StructValidateFunc validate, StructCallbackFunc call, StructFreeFunc free) StructRegisterFunc
Definition RNA_types.hh:752
#define RNA_SUBTYPE_UNIT(subtype)
Definition RNA_types.hh:121
@ PROPOVERRIDE_LIBRARY_INSERTION
Definition RNA_types.hh:380
RawPropertyType
Definition RNA_types.hh:471
@ PROP_RAW_INT8
Definition RNA_types.hh:483
@ PROP_RAW_UINT64
Definition RNA_types.hh:482
@ PROP_RAW_INT
Definition RNA_types.hh:473
@ PROP_RAW_INT64
Definition RNA_types.hh:481
@ PROP_RAW_UNSET
Definition RNA_types.hh:472
@ PROP_RAW_BOOLEAN
Definition RNA_types.hh:476
@ PROP_RAW_CHAR
Definition RNA_types.hh:475
@ PROP_RAW_FLOAT
Definition RNA_types.hh:478
@ PROP_RAW_DOUBLE
Definition RNA_types.hh:477
@ PROP_RAW_UINT8
Definition RNA_types.hh:479
@ PROP_RAW_UINT16
Definition RNA_types.hh:480
@ PROP_RAW_SHORT
Definition RNA_types.hh:474
@ PROP_DYNAMIC
Definition RNA_types.hh:317
@ PROP_CONTEXT_UPDATE
Definition RNA_types.hh:296
@ PROP_ANIMATABLE
Definition RNA_types.hh:220
@ PROP_NEVER_UNLINK
Definition RNA_types.hh:273
@ PROP_EDITABLE
Definition RNA_types.hh:207
@ PROP_ENUM_FLAG
Definition RNA_types.hh:293
@ PROP_LIB_EXCEPTION
Definition RNA_types.hh:213
@ PROP_CONTEXT_PROPERTY_UPDATE
Definition RNA_types.hh:297
@ PROP_ENUM_NO_CONTEXT
Definition RNA_types.hh:319
@ PROP_NEVER_NULL
Definition RNA_types.hh:266
@ PROP_NO_DEG_UPDATE
Definition RNA_types.hh:328
@ PROP_ENUM_NO_TRANSLATE
Definition RNA_types.hh:321
@ PROP_REGISTER
Definition RNA_types.hh:300
@ PROP_DEG_SYNC_ONLY
Definition RNA_types.hh:334
@ PROP_ID_SELF_CHECK
Definition RNA_types.hh:259
@ PROP_IDPROPERTY
Definition RNA_types.hh:315
PropertySubType
Definition RNA_types.hh:135
@ PROP_DIRECTION
Definition RNA_types.hh:165
@ PROP_XYZ
Definition RNA_types.hh:172
@ PROP_ACCELERATION
Definition RNA_types.hh:167
@ PROP_BYTESTRING
Definition RNA_types.hh:143
@ PROP_COLOR
Definition RNA_types.hh:163
@ PROP_AXISANGLE
Definition RNA_types.hh:171
@ PROP_EULER
Definition RNA_types.hh:169
@ PROP_COORDS
Definition RNA_types.hh:177
@ PROP_COLOR_GAMMA
Definition RNA_types.hh:175
@ PROP_TRANSLATION
Definition RNA_types.hh:164
@ PROP_XYZ_LENGTH
Definition RNA_types.hh:173
@ PROP_QUATERNION
Definition RNA_types.hh:170
@ PROP_VELOCITY
Definition RNA_types.hh:166
constexpr PointerRNA PointerRNA_NULL
Definition RNA_types.hh:45
#define C
Definition RandGen.cpp:29
#define ND_SHADING
Definition WM_types.hh:444
#define NC_WINDOW
Definition WM_types.hh:342
#define NC_ID
Definition WM_types.hh:362
#define NA_EDITED
Definition WM_types.hh:550
#define NC_MATERIAL
Definition WM_types.hh:347
volatile int lock
static DBVT_INLINE btScalar size(const btDbvtVolume &a)
Definition btDbvt.cpp:52
SIMD_FORCE_INLINE btScalar length() const
Return the length of the vector.
Definition btVector3.h:257
local_group_size(16, 16) .push_constant(Type b
#define printf
#define offsetof(t, d)
int len
draw_view in_light_buf[] float
draw_view push_constant(Type::INT, "radiance_src") .push_constant(Type capture_info_buf storage_buf(1, Qualifier::READ, "ObjectBounds", "bounds_buf[]") .push_constant(Type draw_view int
#define str(s)
#define GS(x)
Definition iris.cc:202
format
void *(* MEM_mallocN)(size_t len, const char *str)
Definition mallocn.cc:44
void MEM_freeN(void *vmemh)
Definition mallocn.cc:105
void *(* MEM_callocN)(size_t len, const char *str)
Definition mallocn.cc:42
int main()
std::unique_ptr< IDProperty, IDPropertyDeleter > create_bool(StringRefNull prop_name, bool value, eIDPropertyFlag flags={})
Allocate a new IDProperty of type IDP_BOOLEAN, set its name and value.
std::unique_ptr< IDProperty, IDPropertyDeleter > create(StringRefNull prop_name, int32_t value, eIDPropertyFlag flags={})
Allocate a new IDProperty of type IDP_INT, set its name and value.
std::unique_ptr< IDProperty, IDPropertyDeleter > create_group(StringRefNull prop_name, eIDPropertyFlag flags={})
Allocate a new IDProperty of type IDP_GROUP.
void PyC_LineSpit()
return ret
PointerRNA rna_listbase_lookup_int(PointerRNA *ptr, StructRNA *type, ListBase *lb, int index)
StructUnregisterFunc RNA_struct_unregister(StructRNA *type)
float RNA_property_float_get(PointerRNA *ptr, PropertyRNA *prop)
bool RNA_property_is_runtime(const PropertyRNA *prop)
bool RNA_property_collection_lookup_int_has_fn(PropertyRNA *prop)
void RNA_boolean_set_array(PointerRNA *ptr, const char *name, const bool *values)
bool RNA_property_enum_value(bContext *C, PointerRNA *ptr, PropertyRNA *prop, const char *identifier, int *r_value)
StructRegisterFunc RNA_struct_register(StructRNA *type)
bool RNA_property_enum_item_from_value(bContext *C, PointerRNA *ptr, PropertyRNA *prop, const int value, EnumPropertyItem *r_item)
IDProperty * rna_idproperty_find(PointerRNA *ptr, const char *name)
void RNA_property_float_get_default_array(PointerRNA *ptr, PropertyRNA *prop, float *values)
bool RNA_property_enum_identifier(bContext *C, PointerRNA *ptr, PropertyRNA *prop, const int value, const char **r_identifier)
int RNA_enum_bitflag_identifiers(const EnumPropertyItem *item, const int value, const char **r_identifier)
static void rna_property_float_fill_default_array_values_double(const double *default_array, const int default_array_len, const double default_value, const int out_length, float *r_values)
void RNA_int_set_array(PointerRNA *ptr, const char *name, const int *values)
const char * RNA_property_ui_name_raw(const PropertyRNA *prop)
void RNA_property_boolean_set_index(PointerRNA *ptr, PropertyRNA *prop, int index, bool value)
void RNA_property_int_set(PointerRNA *ptr, PropertyRNA *prop, int value)
const StructRNA * RNA_struct_base_child_of(const StructRNA *type, const StructRNA *parent_type)
void RNA_property_int_ui_range(PointerRNA *ptr, PropertyRNA *prop, int *softmin, int *softmax, int *step)
PropertyRNA * RNA_struct_type_find_property(StructRNA *srna, const char *identifier)
const char * RNA_property_ui_description(const PropertyRNA *prop)
bool RNA_property_update_check(PropertyRNA *prop)
bool RNA_property_array_check(PropertyRNA *prop)
bool RNA_struct_is_a(const StructRNA *type, const StructRNA *srna)
PropertyRNA * RNA_struct_find_collection_property_check(PointerRNA &props, const char *name, const StructRNA *struct_type_check)
bool RNA_property_is_unlink(PropertyRNA *prop)
std::string RNA_pointer_as_string_id(bContext *C, PointerRNA *ptr)
void RNA_parameter_get(ParameterList *parms, PropertyRNA *parm, void **r_value)
void rna_property_rna_or_id_get(PropertyRNA *prop, PointerRNA *ptr, PropertyRNAOrID *r_prop_rna_or_id)
StructRNA * RNA_struct_find(const char *identifier)
static void rna_property_int_fill_default_array_values(const int *defarr, int defarr_length, int defvalue, int out_length, int *r_values)
void RNA_property_float_get_array(PointerRNA *ptr, PropertyRNA *prop, float *values)
bool RNA_property_assign_default(PointerRNA *ptr, PropertyRNA *prop)
const char * RNA_function_identifier(FunctionRNA *func)
void RNA_parameter_list_end(ParameterIterator *)
PropertyScaleType RNA_property_ui_scale(PropertyRNA *prop)
void RNA_struct_state_owner_set(const char *name)
static void rna_pointer_inherit_id(const StructRNA *type, const PointerRNA *parent, PointerRNA *ptr)
bool RNA_property_int_set_default(PropertyRNA *prop, int value)
void RNA_struct_py_type_set(StructRNA *srna, void *py_type)
void rna_iterator_array_end(CollectionPropertyIterator *iter)
void RNA_int_get_array(PointerRNA *ptr, const char *name, int *values)
bool RNA_property_path_from_ID_check(PointerRNA *ptr, PropertyRNA *prop)
bool RNA_property_boolean_get_default_index(PointerRNA *ptr, PropertyRNA *prop, int index)
static void rna_property_int_get_default_array_values(PointerRNA *ptr, IntPropertyRNA *iprop, int *r_values)
IDProperty ** RNA_struct_idprops_p(PointerRNA *ptr)
bool RNA_property_float_set_default(PropertyRNA *prop, float value)
void RNA_string_set(PointerRNA *ptr, const char *name, const char *value)
static void rna_property_float_get_default_array_values(PointerRNA *ptr, FloatPropertyRNA *fprop, float *r_values)
const char * RNA_translate_ui_text(const char *text, const char *text_ctxt, StructRNA *type, PropertyRNA *prop, int translate)
static void rna_idproperty_free(PointerRNA *ptr, const char *name)
PointerRNA RNA_pointer_get(PointerRNA *ptr, const char *name)
int RNA_collection_length(PointerRNA *ptr, const char *name)
int RNA_enum_from_name(const EnumPropertyItem *item, const char *name)
int RNA_property_int_clamp(PointerRNA *ptr, PropertyRNA *prop, int *value)
int RNA_parameter_dynamic_length_get_data(ParameterList *, PropertyRNA *parm, void *data)
int RNA_property_float_clamp(PointerRNA *ptr, PropertyRNA *prop, float *value)
int RNA_property_int_get_default(PointerRNA *ptr, PropertyRNA *prop)
void RNA_exit()
Definition rna_access.cc:98
void RNA_pointer_set(PointerRNA *ptr, const char *name, PointerRNA ptr_value)
void RNA_boolean_get_array(PointerRNA *ptr, const char *name, bool *values)
int RNA_property_enum_bitflag_identifiers(bContext *C, PointerRNA *ptr, PropertyRNA *prop, const int value, const char **r_identifier)
bool RNA_struct_available_or_report(ReportList *reports, const char *identifier)
bool RNA_enum_is_equal(bContext *C, PointerRNA *ptr, const char *name, const char *enumname)
PropertyRNA * RNA_struct_find_property_check(PointerRNA &props, const char *name, const PropertyType property_type_check)
bool RNA_struct_is_ID(const StructRNA *type)
int RNA_property_int_get_index(PointerRNA *ptr, PropertyRNA *prop, int index)
char * RNA_property_string_get_default_alloc(PointerRNA *ptr, PropertyRNA *prop, char *fixedbuf, int fixedlen, int *r_len)
void RNA_property_float_ui_range(PointerRNA *ptr, PropertyRNA *prop, float *softmin, float *softmax, float *step, float *precision)
const ListBase * RNA_struct_type_properties(StructRNA *srna)
void RNA_property_float_set_index(PointerRNA *ptr, PropertyRNA *prop, int index, float value)
bool RNA_enum_value_from_id(const EnumPropertyItem *item, const char *identifier, int *r_value)
const ListBase * RNA_struct_type_functions(StructRNA *srna)
PropertyRNA * rna_struct_find_nested(PointerRNA *ptr, StructRNA *srna)
void rna_iterator_listbase_end(CollectionPropertyIterator *)
bool RNA_property_collection_assign_int(PointerRNA *ptr, PropertyRNA *prop, const int key, const PointerRNA *assign_ptr)
static void rna_property_boolean_get_default_array_values(PointerRNA *ptr, BoolPropertyRNA *bprop, bool *r_values)
eStringPropertySearchFlag RNA_property_string_search_flag(PropertyRNA *prop)
bool RNA_property_collection_is_empty(PointerRNA *ptr, PropertyRNA *prop)
PropertyUnit RNA_property_unit(PropertyRNA *prop)
int RNA_property_enum_get_default(PointerRNA *, PropertyRNA *prop)
void RNA_struct_blender_type_set(StructRNA *srna, void *blender_type)
int RNA_function_defined(FunctionRNA *func)
int RNA_property_ui_icon(const PropertyRNA *prop)
static const char * rna_ensure_property_identifier(const PropertyRNA *prop)
int RNA_property_collection_lookup_index(PointerRNA *ptr, PropertyRNA *prop, const PointerRNA *t_ptr)
void RNA_collection_clear(PointerRNA *ptr, const char *name)
bool RNA_property_reset(PointerRNA *ptr, PropertyRNA *prop, int index)
void RNA_parameter_dynamic_length_set(ParameterList *parms, PropertyRNA *parm, int length)
static void rna_array_as_string_elem(int type, void **buf_p, int len, std::stringstream &ss)
StructRNA * RNA_property_pointer_type(PointerRNA *ptr, PropertyRNA *prop)
void RNA_parameter_dynamic_length_set_data(ParameterList *, PropertyRNA *parm, void *data, int length)
PropertyRNA * RNA_struct_find_property(PointerRNA *ptr, const char *identifier)
bool RNA_path_resolved_create(PointerRNA *ptr, PropertyRNA *prop, const int prop_index, PathResolvedRNA *r_anim_rna)
bool RNA_collection_is_empty(PointerRNA *ptr, const char *name)
static const char * bool_as_py_string(const int var)
float RNA_property_float_get_index(PointerRNA *ptr, PropertyRNA *prop, int index)
void RNA_property_pointer_set(PointerRNA *ptr, PropertyRNA *prop, PointerRNA ptr_value, ReportList *reports)
void RNA_property_string_search(const bContext *C, PointerRNA *ptr, PropertyRNA *prop, const char *edit_text, blender::FunctionRef< void(StringPropertySearchVisitParams)> visit_fn)
char * RNA_struct_name_get_alloc(PointerRNA *ptr, char *fixedbuf, int fixedlen, int *r_len)
void _RNA_warning(const char *format,...)
void RNA_boolean_set(PointerRNA *ptr, const char *name, bool value)
const EnumPropertyItem * RNA_struct_property_tag_defines(const StructRNA *type)
void RNA_property_collection_skip(CollectionPropertyIterator *iter, int num)
#define RAW_GET(dtype, var, raw, a)
float RNA_property_float_get_default_index(PointerRNA *ptr, PropertyRNA *prop, int index)
void RNA_pointer_add(PointerRNA *ptr, const char *name)
bool RNA_property_collection_lookup_string_has_nameprop(PropertyRNA *prop)
int RNA_enum_from_identifier(const EnumPropertyItem *item, const char *identifier)
int RNA_property_collection_raw_get(ReportList *reports, PointerRNA *ptr, PropertyRNA *prop, const char *propname, void *array, RawPropertyType type, int len)
std::string RNA_pointer_as_string_keywords_ex(bContext *C, PointerRNA *ptr, const bool as_function, const bool all_args, const bool nested_args, const int max_prop_length, PropertyRNA *iterprop)
uint RNA_enum_items_count(const EnumPropertyItem *item)
bool RNA_property_is_set_ex(PointerRNA *ptr, PropertyRNA *prop, bool use_ghost)
bool RNA_property_editable_index(const PointerRNA *ptr, PropertyRNA *prop, const int index)
const char * RNA_property_ui_description_raw(const PropertyRNA *prop)
bool RNA_property_collection_lookup_string_supported(PropertyRNA *prop)
void RNA_parameter_set(ParameterList *parms, PropertyRNA *parm, const void *value)
bool RNA_struct_property_is_set_ex(PointerRNA *ptr, const char *identifier, bool use_ghost)
bool RNA_property_is_set(PointerRNA *ptr, PropertyRNA *prop)
const char * RNA_property_description(PropertyRNA *prop)
void RNA_property_collection_begin(PointerRNA *ptr, PropertyRNA *prop, CollectionPropertyIterator *iter)
bool RNA_enum_icon_from_value(const EnumPropertyItem *item, int value, int *r_icon)
void RNA_property_float_range(PointerRNA *ptr, PropertyRNA *prop, float *hardmin, float *hardmax)
bool RNA_property_animateable(const PointerRNA *ptr, PropertyRNA *prop_orig)
void RNA_property_boolean_get_array(PointerRNA *ptr, PropertyRNA *prop, bool *values)
PropertyType RNA_property_type(PropertyRNA *prop)
const char * RNA_function_ui_description_raw(FunctionRNA *func)
char * RNA_property_string_get_alloc(PointerRNA *ptr, PropertyRNA *prop, char *fixedbuf, int fixedlen, int *r_len)
void RNA_property_pointer_add(PointerRNA *ptr, PropertyRNA *prop)
static PropertyRNA * arraytypemap[IDP_NUMTYPES]
void RNA_int_set(PointerRNA *ptr, const char *name, int value)
void RNA_property_enum_set(PointerRNA *ptr, PropertyRNA *prop, int value)
PointerRNA RNA_property_pointer_get_default(PointerRNA *, PropertyRNA *)
PointerRNA RNA_property_pointer_get(PointerRNA *ptr, PropertyRNA *prop)
void * RNA_struct_blender_type_get(StructRNA *srna)
void ** RNA_struct_instance(PointerRNA *ptr)
char RNA_property_array_item_char(PropertyRNA *prop, int index)
int RNA_property_enum_step(const bContext *C, PointerRNA *ptr, PropertyRNA *prop, int from_value, int step)
void RNA_parameter_list_free(ParameterList *parms)
static const char * rna_ensure_property_name(const PropertyRNA *prop)
bool RNA_struct_contains_property(PointerRNA *ptr, PropertyRNA *prop_test)
std::string RNA_pointer_as_string_keywords(bContext *C, PointerRNA *ptr, const bool as_function, const bool all_args, const bool nested_args, const int max_prop_length)
IDProperty * RNA_struct_idprops(PointerRNA *ptr, bool create)
void RNA_float_get_array(PointerRNA *ptr, const char *name, float *values)
void rna_idproperty_touch(IDProperty *idprop)
void RNA_property_update(bContext *C, PointerRNA *ptr, PropertyRNA *prop)
void rna_iterator_listbase_begin(CollectionPropertyIterator *iter, ListBase *lb, IteratorSkipFunc skip)
int RNA_property_int_get_default_index(PointerRNA *ptr, PropertyRNA *prop, int index)
size_t RNA_raw_type_sizeof(RawPropertyType type)
PointerRNA rna_array_lookup_int(PointerRNA *ptr, StructRNA *type, void *data, int itemsize, int length, int index)
bool RNA_property_boolean_get(PointerRNA *ptr, PropertyRNA *prop)
void RNA_property_float_get_array_range(PointerRNA *ptr, PropertyRNA *prop, float values[2])
void RNA_property_boolean_get_default_array(PointerRNA *ptr, PropertyRNA *prop, bool *values)
const char * RNA_struct_identifier(const StructRNA *type)
bool RNA_struct_idprops_contains_datablock(const StructRNA *type)
void RNA_property_int_set_index(PointerRNA *ptr, PropertyRNA *prop, int index, int value)
static int rna_property_array_length_all_dimensions(PointerRNA *ptr, PropertyRNA *prop)
bool RNA_property_enum_name_gettexted(bContext *C, PointerRNA *ptr, PropertyRNA *prop, const int value, const char **r_name)
void RNA_property_enum_items_gettexted(bContext *C, PointerRNA *ptr, PropertyRNA *prop, const EnumPropertyItem **r_item, int *r_totitem, bool *r_free)
bool RNA_enum_id_from_value(const EnumPropertyItem *item, int value, const char **r_identifier)
void rna_iterator_array_begin(CollectionPropertyIterator *iter, void *ptr, int itemsize, int length, bool free_ptr, IteratorSkipFunc skip)
int RNA_property_int_get(PointerRNA *ptr, PropertyRNA *prop)
const char * RNA_property_translation_context(const PropertyRNA *prop)
void RNA_property_collection_next(CollectionPropertyIterator *iter)
void RNA_collection_add(PointerRNA *ptr, const char *name, PointerRNA *r_value)
void RNA_parameter_list_next(ParameterIterator *iter)
void * rna_iterator_array_get(CollectionPropertyIterator *iter)
void RNA_enum_set_identifier(bContext *C, PointerRNA *ptr, const char *name, const char *id)
static void * rna_array_as_string_alloc(int type, int len, PointerRNA *ptr, PropertyRNA *prop, void **r_buf_end)
static bool rna_idproperty_verify_valid(PointerRNA *ptr, PropertyRNA *prop, IDProperty *idprop)
void RNA_string_get(PointerRNA *ptr, const char *name, char *value)
static void rna_property_float_fill_default_array_values(const float *defarr, int defarr_length, float defvalue, int out_length, float *r_values)
const char * RNA_function_ui_description(FunctionRNA *func)
int RNA_int_get(PointerRNA *ptr, const char *name)
static void rna_ensure_property_multi_array_length(const PointerRNA *ptr, PropertyRNA *prop, int length[])
int RNA_property_array_dimension(const PointerRNA *ptr, PropertyRNA *prop, int length[])
bool RNA_enum_value_from_identifier(const EnumPropertyItem *item, const char *identifier, int *r_value)
bool RNA_enum_name_from_value(const EnumPropertyItem *item, int value, const char **r_name)
PropertyRNA * RNA_struct_type_find_property_no_base(StructRNA *srna, const char *identifier)
int RNA_function_flag(FunctionRNA *func)
void * RNA_property_py_data_get(PropertyRNA *prop)
std::string RNA_function_as_string_keywords(bContext *C, FunctionRNA *func, const bool as_function, const bool all_args, const int max_prop_length)
void RNA_property_update_main(Main *bmain, Scene *scene, PointerRNA *ptr, PropertyRNA *prop)
float RNA_property_float_get_default(PointerRNA *ptr, PropertyRNA *prop)
bool RNA_property_anim_editable(const PointerRNA *ptr, PropertyRNA *prop_orig)
static bool rna_property_editable_do(const PointerRNA *ptr, PropertyRNA *prop_orig, const int index, const char **r_info)
bool RNA_property_pointer_poll(PointerRNA *ptr, PropertyRNA *prop, PointerRNA *value)
int RNA_property_flag(PropertyRNA *prop)
char * RNA_string_get_alloc(PointerRNA *ptr, const char *name, char *fixedbuf, int fixedlen, int *r_len)
RawPropertyType RNA_property_raw_type(PropertyRNA *prop)
static void rna_property_boolean_fill_default_array_values_from_ints(const int *defarr, int defarr_length, bool defvalue, int out_length, bool *r_values)
const char * RNA_struct_ui_description_raw(const StructRNA *type)
int RNA_struct_ui_icon(const StructRNA *type)
void RNA_property_boolean_set(PointerRNA *ptr, PropertyRNA *prop, bool value)
float RNA_float_get(PointerRNA *ptr, const char *name)
bool RNA_property_builtin(PropertyRNA *prop)
void RNA_property_int_get_array_range(PointerRNA *ptr, PropertyRNA *prop, int values[2])
void rna_iterator_listbase_next(CollectionPropertyIterator *iter)
const char * RNA_struct_ui_description(const StructRNA *type)
int RNA_parameter_list_arg_count(const ParameterList *parms)
bool RNA_property_collection_lookup_int(PointerRNA *ptr, PropertyRNA *prop, int key, PointerRNA *r_ptr)
bool RNA_struct_idprops_register_check(const StructRNA *type)
void RNA_parameter_set_lookup(ParameterList *parms, const char *identifier, const void *value)
static char rna_struct_state_owner[128]
void RNA_property_string_get_default(PropertyRNA *prop, char *value, const int value_maxncpy)
void RNA_property_string_set_bytes(PointerRNA *ptr, PropertyRNA *prop, const char *value, int len)
void RNA_float_set(PointerRNA *ptr, const char *name, float value)
int RNA_string_length(PointerRNA *ptr, const char *name)
static PropertyRNA * typemap[IDP_NUMTYPES]
bool RNA_property_enum_item_from_value_gettexted(bContext *C, PointerRNA *ptr, PropertyRNA *prop, const int value, EnumPropertyItem *r_item)
const char * RNA_struct_ui_name(const StructRNA *type)
bool RNA_struct_undo_check(const StructRNA *type)
void RNA_collection_begin(PointerRNA *ptr, const char *name, CollectionPropertyIterator *iter)
PointerRNA rna_pointer_inherit_refine(const PointerRNA *ptr, StructRNA *type, void *data)
void RNA_struct_property_unset(PointerRNA *ptr, const char *identifier)
void RNA_property_collection_add(PointerRNA *ptr, PropertyRNA *prop, PointerRNA *r_ptr)
bool RNA_pointer_is_null(const PointerRNA *ptr)
int RNA_property_array_length(PointerRNA *ptr, PropertyRNA *prop)
bool RNA_enum_description(const EnumPropertyItem *item, const int value, const char **r_description)
const char * RNA_property_ui_name(const PropertyRNA *prop)
StructRNA * RNA_struct_base(StructRNA *type)
static std::optional< std::string > rna_pointer_as_string__bldata(PointerRNA *ptr)
FunctionRNA * RNA_struct_find_function(StructRNA *srna, const char *identifier)
static int rna_ensure_property_array_length(PointerRNA *ptr, PropertyRNA *prop)
bool RNA_enum_name(const EnumPropertyItem *item, const int value, const char **r_name)
bool RNA_property_is_idprop(const PropertyRNA *prop)
static void rna_property_update(bContext *C, Main *bmain, Scene *scene, PointerRNA *ptr, PropertyRNA *prop)
int RNA_property_string_maxlength(PropertyRNA *prop)
void RNA_property_enum_items_gettexted_all(bContext *C, PointerRNA *ptr, PropertyRNA *prop, const EnumPropertyItem **r_item, int *r_totitem, bool *r_free)
const char * RNA_struct_state_owner_get()
std::optional< std::string > RNA_pointer_as_string(bContext *C, PointerRNA *ptr, PropertyRNA *prop_ptr, PointerRNA *ptr_prop)
bool RNA_struct_idprops_datablock_allowed(const StructRNA *type)
static void rna_array_as_string(int type, int len, PointerRNA *ptr, PropertyRNA *prop, std::stringstream &ss)
int RNA_property_string_default_length(PointerRNA *, PropertyRNA *prop)
bool RNA_property_editable(const PointerRNA *ptr, PropertyRNA *prop)
bool RNA_property_collection_lookup_string_index(PointerRNA *ptr, PropertyRNA *prop, const char *key, PointerRNA *r_ptr, int *r_index)
void RNA_property_float_set_array(PointerRNA *ptr, PropertyRNA *prop, const float *values)
void RNA_property_int_set_array(PointerRNA *ptr, PropertyRNA *prop, const int *values)
void RNA_property_int_get_default_array(PointerRNA *ptr, PropertyRNA *prop, int *values)
static bool property_collection_liboverride_editable(PointerRNA *ptr, PropertyRNA *prop, bool *r_is_liboverride)
bool RNA_property_enum_name(bContext *C, PointerRNA *ptr, PropertyRNA *prop, const int value, const char **r_name)
bool RNA_property_editable_info(const PointerRNA *ptr, PropertyRNA *prop, const char **r_info)
int RNA_property_enum_get(PointerRNA *ptr, PropertyRNA *prop)
void rna_iterator_array_next(CollectionPropertyIterator *iter)
PointerRNA RNA_pointer_recast(PointerRNA *ptr)
void RNA_property_float_set(PointerRNA *ptr, PropertyRNA *prop, float value)
PropertyRNA * RNA_struct_name_property(const StructRNA *type)
static const char * rna_ensure_property_description(const PropertyRNA *prop)
std::string RNA_property_string_get(PointerRNA *ptr, PropertyRNA *prop)
void RNA_property_int_get_array(PointerRNA *ptr, PropertyRNA *prop, int *values)
bool RNA_property_collection_move(PointerRNA *ptr, PropertyRNA *prop, int key, int pos)
int RNA_enum_from_value(const EnumPropertyItem *item, const int value)
PropertySubType RNA_property_subtype(PropertyRNA *prop)
bool RNA_struct_property_is_set(PointerRNA *ptr, const char *identifier)
int RNA_parameter_list_ret_count(const ParameterList *parms)
PointerRNA RNA_main_pointer_create(Main *main)
void RNA_property_int_range(PointerRNA *ptr, PropertyRNA *prop, int *hardmin, int *hardmax)
bool RNA_struct_idprops_unset(PointerRNA *ptr, const char *identifier)
bool RNA_boolean_get(PointerRNA *ptr, const char *name)
int RNA_function_call(bContext *C, ReportList *reports, PointerRNA *ptr, FunctionRNA *func, ParameterList *parms)
int RNA_parameter_dynamic_length_get(ParameterList *parms, PropertyRNA *parm)
static void rna_array_as_string_recursive(int type, void **buf_p, int totdim, const int *dim_size, std::stringstream &ss)
static CLG_LogRef LOG
Definition rna_access.cc:69
const char * RNA_struct_ui_name_raw(const StructRNA *type)
bool RNA_property_collection_lookup_string(PointerRNA *ptr, PropertyRNA *prop, const char *key, PointerRNA *r_ptr)
ParameterList * RNA_parameter_list_create(ParameterList *parms, PointerRNA *, FunctionRNA *func)
void RNA_property_enum_items(bContext *C, PointerRNA *ptr, PropertyRNA *prop, const EnumPropertyItem **r_item, int *r_totitem, bool *r_free)
PropertyRNA * RNA_function_get_parameter(PointerRNA *, FunctionRNA *func, int index)
bool RNA_property_driver_editable(const PointerRNA *ptr, PropertyRNA *prop)
void RNA_property_collection_clear(PointerRNA *ptr, PropertyRNA *prop)
int RNA_property_tags(PropertyRNA *prop)
bool RNA_enum_identifier(const EnumPropertyItem *item, const int value, const char **r_identifier)
void * rna_iterator_array_dereference_get(CollectionPropertyIterator *iter)
static bool rna_ensure_property_array_check(PropertyRNA *prop)
bool RNA_property_collection_type_get(PointerRNA *ptr, PropertyRNA *prop, PointerRNA *r_ptr)
void RNA_property_collection_end(CollectionPropertyIterator *iter)
bool RNA_property_collection_lookup_string_has_fn(PropertyRNA *prop)
bool RNA_struct_idprops_check(StructRNA *srna)
void RNA_enum_set(PointerRNA *ptr, const char *name, int value)
void RNA_float_set_array(PointerRNA *ptr, const char *name, const float *values)
int RNA_property_array_item_index(PropertyRNA *prop, char name)
static void rna_property_boolean_fill_default_array_values(const bool *defarr, int defarr_length, bool defvalue, int out_length, bool *r_values)
PointerRNA RNA_blender_rna_pointer_create()
PointerRNA RNA_pointer_create(ID *id, StructRNA *type, void *data)
bool RNA_property_boolean_get_index(PointerRNA *ptr, PropertyRNA *prop, int index)
bool RNA_property_boolean_get_default(PointerRNA *ptr, PropertyRNA *prop)
bool RNA_struct_bl_idname_ok_or_report(ReportList *reports, const char *identifier, const char *sep)
bool RNA_property_collection_remove(PointerRNA *ptr, PropertyRNA *prop, int key)
int RNA_enum_get(PointerRNA *ptr, const char *name)
void * rna_iterator_listbase_get(CollectionPropertyIterator *iter)
#define RAW_SET(dtype, raw, a, var)
void RNA_property_unset(PointerRNA *ptr, PropertyRNA *prop)
uint RNA_struct_count_properties(StructRNA *srna)
void RNA_parameter_list_begin(ParameterList *parms, ParameterIterator *iter)
IDProperty * rna_idproperty_check(PropertyRNA **prop, PointerRNA *ptr)
void RNA_property_pointer_remove(PointerRNA *ptr, PropertyRNA *prop)
std::string RNA_property_as_string(bContext *C, PointerRNA *ptr, PropertyRNA *prop, int index, int max_prop_length)
int RNA_property_string_length(PointerRNA *ptr, PropertyRNA *prop)
PropertyRNA * RNA_struct_iterator_property(StructRNA *type)
void RNA_property_enum_items_ex(bContext *C, PointerRNA *ptr, PropertyRNA *prop, const bool use_static, const EnumPropertyItem **r_item, int *r_totitem, bool *r_free)
void RNA_init()
Definition rna_access.cc:73
int RNA_parameter_list_size(const ParameterList *parms)
int RNA_parameter_flag(PropertyRNA *prop)
void RNA_parameter_get_lookup(ParameterList *parms, const char *identifier, void **r_value)
void * RNA_struct_py_type_get(StructRNA *srna)
bool RNA_property_editable_flag(const PointerRNA *ptr, PropertyRNA *prop)
PropertyRNA * RNA_function_find_parameter(PointerRNA *, FunctionRNA *func, const char *identifier)
const char * RNA_struct_translation_context(const StructRNA *type)
int RNA_property_collection_raw_set(ReportList *reports, PointerRNA *ptr, PropertyRNA *prop, const char *propname, void *array, RawPropertyType type, int len)
bool RNA_property_animated(PointerRNA *ptr, PropertyRNA *prop)
const char * RNA_property_identifier(const PropertyRNA *prop)
int RNA_property_collection_raw_array(PointerRNA *ptr, PropertyRNA *prop, PropertyRNA *itemprop, bool set, RawArray *array)
const ListBase * RNA_function_defined_parameters(FunctionRNA *func)
int RNA_property_multi_array_length(PointerRNA *ptr, PropertyRNA *prop, int dim)
static const char * rna_property_type_identifier(PropertyType prop_type)
PropertyRNA * rna_ensure_property(PropertyRNA *prop)
static int rna_raw_access(ReportList *reports, PointerRNA *ptr, PropertyRNA *prop, const char *propname, void *inarray, RawPropertyType intype, int inlen, int set)
int RNA_property_collection_length(PointerRNA *ptr, PropertyRNA *prop)
void RNA_property_boolean_set_array(PointerRNA *ptr, PropertyRNA *prop, const bool *values)
PointerRNA RNA_id_pointer_create(ID *id)
void RNA_property_string_set(PointerRNA *ptr, PropertyRNA *prop, const char *value)
static void rna_property_collection_get_idp(CollectionPropertyIterator *iter)
bool RNA_property_overridable_get(const PointerRNA *ptr, PropertyRNA *prop)
void RNA_free(BlenderRNA *brna)
void RNA_enum_item_end(EnumPropertyItem **items, int *totitem)
void RNA_enum_item_add(EnumPropertyItem **items, int *totitem, const EnumPropertyItem *item)
int rna_parameter_size(PropertyRNA *parm)
int rna_parameter_size_pad(const int size)
StructRNA * rna_ID_refine(PointerRNA *ptr)
BlenderRNA BLENDER_RNA
#define RNA_MAGIC
const char * rna_translate_ui_text(const char *text, const char *text_ctxt, StructRNA *type, PropertyRNA *prop, bool translate)
void(*)(bContext *C, PointerRNA *ptr, PropertyRNA *prop) ContextPropUpdateFunc
void(*)(bContext *C, PointerRNA *ptr) ContextUpdateFunc
@ PROP_INTERN_BUILTIN
@ PROP_INTERN_RAW_ACCESS
@ PROP_INTERN_RAW_ARRAY
@ PROP_INTERN_RUNTIME
bool(*)(PointerRNA *ptr, const PointerRNA value, const PropertyRNA *prop) PropPointerPollFuncPy
std::optional< std::string > RNA_path_full_struct_py(const PointerRNA *ptr)
Definition rna_path.cc:1260
std::string RNA_path_full_ID_py(ID *id)
Definition rna_path.cc:1225
std::optional< std::string > RNA_path_from_ID_to_property(const PointerRNA *ptr, PropertyRNA *prop)
Definition rna_path.cc:1166
bool RNA_path_resolve_property(const PointerRNA *ptr, const char *path, PointerRNA *r_ptr, PropertyRNA **r_prop)
Definition rna_path.cc:553
bool RNA_path_resolve(const PointerRNA *ptr, const char *path, PointerRNA *r_ptr, PropertyRNA **r_prop)
Definition rna_path.cc:525
#define min(a, b)
Definition sort.c:32
#define FLT_MAX
Definition stdcycles.h:14
unsigned short uint16_t
Definition stdint.h:79
__int64 int64_t
Definition stdint.h:89
_W64 int intptr_t
Definition stdint.h:118
unsigned char uint8_t
Definition stdint.h:78
unsigned __int64 uint64_t
Definition stdint.h:90
signed char int8_t
Definition stdint.h:75
bAction * action
void * free_ptr
Definition RNA_types.hh:426
IteratorSkipFunc skip
Definition RNA_types.hh:440
unsigned int structs_len
PropBooleanGetFuncEx get_default
PropBooleanArraySetFuncEx setarray_ex
PropBooleanArrayGetFuncEx getarray_ex
PropBooleanArraySetFunc setarray
const bool * defaultarray
PropBooleanArrayGetFuncEx get_default_array
PropBooleanSetFunc set
PropBooleanGetFunc get
PropBooleanSetFuncEx set_ex
PropBooleanGetFuncEx get_ex
PropBooleanArrayGetFunc getarray
ListBaseIterator listbase
Definition RNA_types.hh:455
union CollectionPropertyIterator::@1329 internal
PropCollectionNextFunc next
PropCollectionLookupStringFunc lookupstring
PropCollectionLengthFunc length
PropCollectionLookupIntFunc lookupint
PropCollectionBeginFunc begin
PropCollectionAssignIntFunc assignint
PropCollectionEndFunc end
struct GHash * prophash
const char * identifier
Definition RNA_types.hh:506
const char * name
Definition RNA_types.hh:510
const char * description
Definition RNA_types.hh:512
const EnumPropertyItem * item
PropEnumSetFuncEx set_ex
PropEnumGetFunc get
PropEnumItemFunc item_fn
PropEnumGetFuncEx get_ex
PropEnumSetFunc set
PropFloatSetFuncEx set_ex
PropertyScaleType ui_scale_type
PropFloatGetFunc get
PropFloatRangeFuncEx range_ex
PropFloatArrayGetFuncEx getarray_ex
PropFloatArraySetFuncEx setarray_ex
PropFloatArrayGetFunc getarray
PropFloatGetFuncEx get_default
PropFloatSetFunc set
const float * defaultarray
PropFloatRangeFunc range
PropFloatArraySetFunc setarray
PropFloatGetFuncEx get_ex
PropFloatArrayGetFuncEx get_default_array
const char * identifier
ContainerRNA cont
const char * description
struct ID * reference
Definition DNA_ID.h:333
void * pointer
Definition DNA_ID.h:145
int8_t * default_array
Definition DNA_ID.h:100
double * default_array
Definition DNA_ID.h:110
IDPropertyUIDataEnumItem * enum_items
Definition DNA_ID.h:94
int * default_array
Definition DNA_ID.h:83
char * description
Definition DNA_ID.h:59
short flag
Definition DNA_ID.h:161
int len
Definition DNA_ID.h:174
IDPropertyUIData * ui_data
Definition DNA_ID.h:182
char name[64]
Definition DNA_ID.h:163
IDPropertyData data
Definition DNA_ID.h:168
char subtype
Definition DNA_ID.h:159
char type
Definition DNA_ID.h:154
Definition DNA_ID.h:413
char name[66]
Definition DNA_ID.h:425
PropIntRangeFuncEx range_ex
PropIntArrayGetFunc getarray
PropIntArrayGetFuncEx getarray_ex
PropIntRangeFunc range
PropIntArraySetFunc setarray
PropIntGetFuncEx get_ex
PropIntArrayGetFuncEx get_default_array
PropIntArraySetFuncEx setarray_ex
PropertyScaleType ui_scale_type
PropIntGetFuncEx get_default
PropIntSetFuncEx set_ex
IteratorSkipFunc skip
Definition RNA_types.hh:418
void * first
ParameterList * parms
Definition RNA_types.hh:631
PropertyRNA * parm
Definition RNA_types.hh:636
FunctionRNA * func
Definition RNA_types.hh:622
PointerRNA ptr
Definition RNA_types.hh:56
PropertyRNA * prop
Definition RNA_types.hh:57
PropPointerTypeFunc type_fn
PropPointerGetFunc get
PropPointerPollFunc poll
PropPointerSetFunc set
ID * owner_id
Definition RNA_types.hh:40
StructRNA * type
Definition RNA_types.hh:41
void * data
Definition RNA_types.hh:42
ItemEditableFunc itemeditable
PropArrayLengthGetFunc getlength
const char * translation_context
unsigned int arraydimension
EditableFunc editable
PropertyRNA * next
PropertySubType subtype
unsigned int arraylength[RNA_MAX_ARRAY_DIMENSION]
const char * description
const char * name
unsigned int totarraylength
const char * identifier
RawPropertyType rawtype
PropertyType type
void * array
Definition RNA_types.hh:487
PropStringSetFunc set
PropStringLengthFuncEx length_ex
PropStringLengthFunc length
PropStringGetFuncEx get_ex
PropStringSetFuncEx set_ex
PropStringGetFunc get
StringPropertySearchFunc search
eStringPropertySearchFlag search_flag
const char * identifier
StructInstanceFunc instance
ContainerRNA cont
PropertyRNA * nameproperty
IDPropertiesFunc idproperties
StructRNA * base
StructRefineFunc refine
float max
const char * str
Definition BKE_idprop.hh:37
struct IDPropertyTemplate::@30 array
struct IDPropertyTemplate::@29 string
#define N_(msgid)
void WM_main_add_notifier(uint type, void *reference)
PointerRNA * ptr
Definition wm_files.cc:4126
void WM_msg_publish_rna(wmMsgBus *mbus, PointerRNA *ptr, PropertyRNA *prop)
uint8_t flag
Definition wm_window.cc:138