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