Blender V4.5
rna_rna.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 <cstdlib>
10
11#include <CLG_log.h>
12
13#include "BLT_translation.hh"
14
15#include "RNA_define.hh"
16#include "RNA_enum_types.hh"
17
18#include "rna_internal.hh"
19
20/* -------------------------------------------------------------------- */
23
24/* Reuse for dynamic types. */
25
27 {0, nullptr, 0, nullptr, nullptr},
28};
29
30/* Reuse for dynamic types with default value. */
31
33 {0, "DEFAULT", 0, "Default", ""},
34 {0, nullptr, 0, nullptr, nullptr},
35};
36
38
39/* -------------------------------------------------------------------- */
42
44 {PROP_BOOLEAN, "BOOLEAN", 0, "Boolean", ""},
45 {PROP_INT, "INT", 0, "Integer", ""},
46 {PROP_FLOAT, "FLOAT", 0, "Float", ""},
47 {PROP_STRING, "STRING", 0, "String", ""},
48 {PROP_ENUM, "ENUM", 0, "Enumeration", ""},
49 {PROP_POINTER, "POINTER", 0, "Pointer", ""},
50 {PROP_COLLECTION, "COLLECTION", 0, "Collection", ""},
51 {0, nullptr, 0, nullptr, nullptr},
52};
53
54/* Wraps multiple enums onto a single line in a way that is difficult to read.
55 * NOTE: these enums are split up based on their use in `bpy.props` Python module. */
56
57/* clang-format off */
58#define RNA_ENUM_PROPERTY_SUBTYPE_STRING_ITEMS \
59 {PROP_FILEPATH, "FILE_PATH", 0, "File Path", ""}, \
60 {PROP_DIRPATH, "DIR_PATH", 0, "Directory Path", ""}, \
61 {PROP_FILENAME, "FILE_NAME", 0, "File Name", ""}, \
62 {PROP_BYTESTRING, "BYTE_STRING", 0, "Byte String", ""}, \
63 {PROP_PASSWORD, "PASSWORD", 0, "Password", "A string that is displayed hidden ('********')"}
64
65#define RNA_ENUM_PROPERTY_SUBTYPE_NUMBER_ITEMS \
66 {PROP_PIXEL, "PIXEL", 0, "Pixel", "A distance on screen"}, \
67 {PROP_UNSIGNED, "UNSIGNED", 0, "Unsigned", ""}, \
68 {PROP_PERCENTAGE, "PERCENTAGE", 0, "Percentage", "A percentage between 0 and 100"}, \
69 {PROP_FACTOR, "FACTOR", 0, "Factor", "A factor between 0.0 and 1.0"}, \
70 {PROP_ANGLE, "ANGLE", 0, "Angle", "A rotational value specified in radians"}, \
71 {PROP_TIME, "TIME", 0, "Time (Scene Relative)", \
72 "Time specified in frames, converted to seconds based on scene frame rate"}, \
73 {PROP_TIME_ABSOLUTE, "TIME_ABSOLUTE", 0, "Time (Absolute)", \
74 "Time specified in seconds, independent of the scene"}, \
75 {PROP_DISTANCE, "DISTANCE", 0, "Distance", "A distance between two points"}, \
76 {PROP_DISTANCE_CAMERA, "DISTANCE_CAMERA", 0, "Camera Distance", ""}, \
77 {PROP_POWER, "POWER", 0, "Power", ""}, \
78 {PROP_TEMPERATURE, "TEMPERATURE", 0, "Temperature", ""}, \
79 {PROP_WAVELENGTH, "WAVELENGTH", 0, "Wavelength", ""}, \
80 {PROP_COLOR_TEMPERATURE, "COLOR_TEMPERATURE", 0, "Color Temperature", ""}, \
81 {PROP_FREQUENCY, "FREQUENCY", 0, "Frequency", ""}
82
83#define RNA_ENUM_PROPERTY_SUBTYPE_NUMBER_ARRAY_ITEMS \
84 {PROP_COLOR, "COLOR", 0, "Linear Color", "Color in the linear space"}, \
85 {PROP_TRANSLATION, "TRANSLATION", 0, "Translation", "Color in the gamma corrected space"}, \
86 {PROP_DIRECTION, "DIRECTION", 0, "Direction", ""}, \
87 {PROP_VELOCITY, "VELOCITY", 0, "Velocity", ""}, \
88 {PROP_ACCELERATION, "ACCELERATION", 0, "Acceleration", ""}, \
89 {PROP_MATRIX, "MATRIX", 0, "Matrix", ""}, \
90 {PROP_EULER, "EULER", 0, "Euler Angles", "Euler rotation angles in radians"}, \
91 {PROP_QUATERNION, "QUATERNION", 0, "Quaternion", "Quaternion rotation (affects NLA blending)"}, \
92 {PROP_AXISANGLE, "AXISANGLE", 0, "Axis-Angle", "Angle and axis to rotate around"}, \
93 {PROP_XYZ, "XYZ", 0, "XYZ", ""}, \
94 {PROP_XYZ_LENGTH, "XYZ_LENGTH", 0, "XYZ Length", ""}, \
95 {PROP_COLOR_GAMMA, "COLOR_GAMMA", 0, "Gamma-Corrected Color", ""}, \
96 {PROP_COORDS, "COORDINATES", 0, "Coordinates", ""}, \
97 /* Boolean. */ \
98 {PROP_LAYER, "LAYER", 0, "Layer", ""}, \
99 {PROP_LAYER_MEMBER, "LAYER_MEMBER", 0, "Layer Member", ""}
100
101/* clang-format on */
102
105
106 {PROP_NONE, "NONE", 0, "None", ""},
107 {0, nullptr, 0, nullptr, nullptr},
108};
109
112
113 {PROP_NONE, "NONE", 0, "None", ""},
114 {0, nullptr, 0, nullptr, nullptr},
115};
116
119
120 {PROP_NONE, "NONE", 0, "None", ""},
121 {0, nullptr, 0, nullptr, nullptr},
122};
123
125 {PROP_NONE, "NONE", 0, "None", ""},
126
127 /* String. */
129
130 /* Number. */
132
133 /* Number array. */
135
136 {0, nullptr, 0, nullptr, nullptr},
137};
138
140 {PROP_UNIT_NONE, "NONE", 0, "None", ""},
141 {PROP_UNIT_LENGTH, "LENGTH", 0, "Length", ""},
142 {PROP_UNIT_AREA, "AREA", 0, "Area", ""},
143 {PROP_UNIT_VOLUME, "VOLUME", 0, "Volume", ""},
144 {PROP_UNIT_ROTATION, "ROTATION", 0, "Rotation", ""},
145 {PROP_UNIT_TIME, "TIME", 0, "Time (Scene Relative)", ""},
146 {PROP_UNIT_TIME_ABSOLUTE, "TIME_ABSOLUTE", 0, "Time (Absolute)", ""},
147 {PROP_UNIT_VELOCITY, "VELOCITY", 0, "Velocity", ""},
148 {PROP_UNIT_ACCELERATION, "ACCELERATION", 0, "Acceleration", ""},
149 {PROP_UNIT_MASS, "MASS", 0, "Mass", ""},
150 {PROP_UNIT_CAMERA, "CAMERA", 0, "Camera", ""},
151 {PROP_UNIT_POWER, "POWER", 0, "Power", ""},
152 {PROP_UNIT_TEMPERATURE, "TEMPERATURE", 0, "Temperature", ""},
153 {PROP_UNIT_WAVELENGTH, "WAVELENGTH", 0, "Wavelength", ""},
154 {PROP_UNIT_COLOR_TEMPERATURE, "COLOR_TEMPERATURE", 0, "Color Temperature", ""},
155 {PROP_UNIT_FREQUENCY, "FREQUENCY", 0, "Frequency", ""},
156 {0, nullptr, 0, nullptr, nullptr},
157};
158
159/* Descriptions for rna_enum_property_flag_items and rna_enum_property_flag_enum_items. */
160static constexpr auto PROP_HIDDEN_DESCR =
161 "For operators: hide from places in the user interface where Blender would add the property "
162 "automatically, like Adjust Last Operation. Also this property is not written to presets.";
163static constexpr auto PROP_SKIP_SAVE_DESCR =
164 "For operators: the value of this property will not be remembered between invocations of the "
165 "operator; instead, each invocation will start by using the default value. Also this "
166 "property is not written to presets.";
167static constexpr auto PROP_SKIP_PRESET_DESCR = "Do not write in presets";
168static constexpr auto PROP_ANIMATABLE_DESCR = "";
169static constexpr auto PROP_LIB_EXCEPTION_DESCR =
170 "This property can be edited, even when it is used on linked data (which normally is "
171 "read-only). Note that edits to the property will not be saved to the blend file.";
172static constexpr auto PROP_PROPORTIONAL_DESCR = "";
173static constexpr auto PROP_TEXTEDIT_UPDATE_DESCR = "";
174static constexpr auto PROP_PATH_OUTPUT_DESCR = "";
175static constexpr auto PROP_PATH_RELATIVE_DESCR =
176 "This path supports relative prefix \"//\" which is expanded the directory "
177 "where the current \".blend\" file is located.";
179 "This path supports the \"{variable_name}\" template syntax, which substitutes the "
180 "value of the referenced variable in place of the template expression";
181static constexpr auto PROP_ENUM_FLAG_DESCR = "";
182
184 {PROP_HIDDEN, "HIDDEN", 0, "Hidden", PROP_HIDDEN_DESCR},
185 {PROP_SKIP_SAVE, "SKIP_SAVE", 0, "Skip Save", PROP_SKIP_SAVE_DESCR},
186 {PROP_SKIP_PRESET, "SKIP_PRESET", 0, "Skip Preset", PROP_SKIP_PRESET_DESCR},
187 {PROP_ANIMATABLE, "ANIMATABLE", 0, "Animatable", PROP_ANIMATABLE_DESCR},
188 {PROP_LIB_EXCEPTION, "LIBRARY_EDITABLE", 0, "Library Editable", PROP_LIB_EXCEPTION_DESCR},
190 "PROPORTIONAL",
191 0,
192 "Adjust values proportionally to each other",
195 "TEXTEDIT_UPDATE",
196 0,
197 "Update on every keystroke in textedit 'mode'",
199 {PROP_PATH_OUTPUT, "OUTPUT_PATH", 0, "Output Path", PROP_PATH_OUTPUT_DESCR},
201 "PATH_SUPPORTS_BLEND_RELATIVE",
202 0,
203 "Relative Path Support",
206 "SUPPORTS_TEMPLATES",
207 0,
208 "Variable expression support",
210 {0, nullptr, 0, nullptr, nullptr},
211};
212
215 {PROP_HIDDEN, "HIDDEN", 0, "Hidden", PROP_HIDDEN_DESCR},
216 {PROP_SKIP_SAVE, "SKIP_SAVE", 0, "Skip Save", PROP_SKIP_SAVE_DESCR},
217 {PROP_ANIMATABLE, "ANIMATABLE", 0, "Animatable", PROP_ANIMATABLE_DESCR},
218 {PROP_LIB_EXCEPTION, "LIBRARY_EDITABLE", 0, "Library Editable", PROP_LIB_EXCEPTION_DESCR},
219 {PROP_ENUM_FLAG, "ENUM_FLAG", 0, "Enum Flag", PROP_ENUM_FLAG_DESCR},
220 {0, nullptr, 0, nullptr, nullptr},
221};
222
225 "LIBRARY_OVERRIDABLE",
226 0,
227 "Library Overridable",
228 "Make that property editable in library overrides of linked data-blocks.\n"
229 "NOTE: For a property to be overridable, its whole chain of parent properties must also be "
230 "defined as overridable"};
231
236
240 "NO_PROPERTY_NAME",
241 0,
242 "No Name",
243 "Do not use the names of the items, only their indices in the collection"},
245 "USE_INSERTION",
246 0,
247 "Use Insertion",
248 "Allow users to add new items in that collection in library overrides"},
249 {0, nullptr, 0, nullptr, nullptr},
250};
251
253 {PROP_STRING_SEARCH_SORT, "SORT", 0, "Sort Search Results", ""},
255 "SUGGESTION",
256 0,
257 "Suggestion",
258 "Search results are suggestions (other values may be entered)"},
259
260 {0, nullptr, 0, nullptr, nullptr},
261};
262
264
265#ifdef RNA_RUNTIME
266# include "BLI_ghash.h"
267# include "BLI_string.h"
268# include "MEM_guardedalloc.h"
269
270# include "BKE_idprop.hh"
271# include "BKE_lib_override.hh"
272
273# include "RNA_path.hh"
274
275# include <optional>
276# include <string>
277
278# include <fmt/format.h>
279
280static CLG_LogRef LOG_COMPARE_OVERRIDE = {"rna.rna_compare_override"};
281
282/* Struct */
283
284static void rna_Struct_identifier_get(PointerRNA *ptr, char *value)
285{
286 strcpy(value, ((StructRNA *)ptr->data)->identifier);
287}
288
289static int rna_Struct_identifier_length(PointerRNA *ptr)
290{
291 return strlen(((StructRNA *)ptr->data)->identifier);
292}
293
294static void rna_Struct_description_get(PointerRNA *ptr, char *value)
295{
296 strcpy(value, ((StructRNA *)ptr->data)->description);
297}
298
299static int rna_Struct_description_length(PointerRNA *ptr)
300{
301 return strlen(((StructRNA *)ptr->data)->description);
302}
303
304static void rna_Struct_name_get(PointerRNA *ptr, char *value)
305{
306 strcpy(value, ((StructRNA *)ptr->data)->name);
307}
308
309static int rna_Struct_name_length(PointerRNA *ptr)
310{
311 return strlen(((StructRNA *)ptr->data)->name);
312}
313
314static void rna_Struct_translation_context_get(PointerRNA *ptr, char *value)
315{
316 strcpy(value, ((StructRNA *)ptr->data)->translation_context);
317}
318
319static int rna_Struct_translation_context_length(PointerRNA *ptr)
320{
321 return strlen(((StructRNA *)ptr->data)->translation_context);
322}
323
324static PointerRNA rna_Struct_base_get(PointerRNA *ptr)
325{
326 return RNA_pointer_create_discrete(nullptr, &RNA_Struct, ((StructRNA *)ptr->data)->base);
327}
328
329static PointerRNA rna_Struct_nested_get(PointerRNA *ptr)
330{
331 return RNA_pointer_create_discrete(nullptr, &RNA_Struct, ((StructRNA *)ptr->data)->nested);
332}
333
334static PointerRNA rna_Struct_name_property_get(PointerRNA *ptr)
335{
337 nullptr, &RNA_Property, ((StructRNA *)ptr->data)->nameproperty);
338}
339
340/* Struct property iteration. This is quite complicated, the purpose is to
341 * iterate over properties of all inheritance levels, and for each struct to
342 * also iterator over id properties not known by RNA. */
343
344static bool rna_idproperty_known(CollectionPropertyIterator *iter, void *data)
345{
346 IDProperty *idprop = (IDProperty *)data;
347 PropertyRNA *prop;
348 StructRNA *ptype = iter->builtin_parent.type;
349
350 /* Function to skip any id properties that are already known by RNA,
351 * for the second loop where we go over unknown id properties.
352 *
353 * Note that only dynamically-defined RNA properties (the ones actually using IDProperties as
354 * storage back-end) should be checked here. If a custom property is named the same as a 'normal'
355 * RNA property, they are different data. */
356 do {
357 for (prop = static_cast<PropertyRNA *>(ptype->cont.properties.first); prop; prop = prop->next)
358 {
359 if ((prop->flag_internal & PROP_INTERN_BUILTIN) == 0 &&
360 (prop->flag & PROP_IDPROPERTY) != 0 && STREQ(prop->identifier, idprop->name))
361 {
362 return true;
363 }
364 }
365 } while ((ptype = ptype->base));
366
367 return false;
368}
369
370static bool rna_property_builtin(CollectionPropertyIterator * /*iter*/, void *data)
371{
372 PropertyRNA *prop = (PropertyRNA *)data;
373
374 /* function to skip builtin rna properties */
375
376 return (prop->flag_internal & PROP_INTERN_BUILTIN) != 0;
377}
378
379static bool rna_function_builtin(CollectionPropertyIterator * /*iter*/, void *data)
380{
381 FunctionRNA *func = (FunctionRNA *)data;
382
383 /* function to skip builtin rna functions */
384
385 return (func->flag & FUNC_BUILTIN) != 0;
386}
387
388static void rna_inheritance_next_level_restart(CollectionPropertyIterator *iter,
390 IteratorSkipFunc skip,
391 int funcs)
392{
393 /* RNA struct inheritance */
394 while (!iter->valid && iter->level > 0) {
395 StructRNA *srna;
396 int i;
397
398 srna = (StructRNA *)iter->parent.data;
399 iter->level--;
400 for (i = iter->level; i > 0; i--) {
401 srna = srna->base;
402 }
403
405
406 if (funcs) {
407 rna_iterator_listbase_begin(iter, ptr, &srna->functions, skip);
408 }
409 else {
410 rna_iterator_listbase_begin(iter, ptr, &srna->cont.properties, skip);
411 }
412 }
413}
414
415static void rna_inheritance_properties_listbase_begin(CollectionPropertyIterator *iter,
417 ListBase *lb,
418 IteratorSkipFunc skip)
419{
420 rna_iterator_listbase_begin(iter, ptr, lb, skip);
421 rna_inheritance_next_level_restart(iter, ptr, skip, 0);
422}
423
424static void rna_inheritance_properties_listbase_next(CollectionPropertyIterator *iter,
425 IteratorSkipFunc skip)
426{
428 rna_inheritance_next_level_restart(iter, &iter->parent, skip, 0);
429}
430
431static void rna_inheritance_functions_listbase_begin(CollectionPropertyIterator *iter,
433 ListBase *lb,
434 IteratorSkipFunc skip)
435{
436 rna_iterator_listbase_begin(iter, ptr, lb, skip);
437 rna_inheritance_next_level_restart(iter, ptr, skip, 1);
438}
439
440static void rna_inheritance_functions_listbase_next(CollectionPropertyIterator *iter,
441 IteratorSkipFunc skip)
442{
444 rna_inheritance_next_level_restart(iter, &iter->parent, skip, 1);
445}
446
447static void rna_Struct_properties_next(CollectionPropertyIterator *iter)
448{
449 ListBaseIterator *internal = &iter->internal.listbase;
450 IDProperty *group;
451
452 if (internal->flag) {
453 /* id properties */
455 }
456 else {
457 /* regular properties */
458 rna_inheritance_properties_listbase_next(iter, rna_property_builtin);
459
460 /* try id properties */
461 if (!iter->valid) {
462 group = RNA_struct_idprops(&iter->builtin_parent, 0);
463
464 if (group) {
466 rna_iterator_listbase_begin(iter, &iter->parent, &group->data.group, rna_idproperty_known);
467 internal = &iter->internal.listbase;
468 internal->flag = 1;
469 }
470 }
471 }
472}
473
474static void rna_Struct_properties_begin(CollectionPropertyIterator *iter, PointerRNA *ptr)
475{
476 StructRNA *srna;
477
478 /* here ptr->data should always be the same as iter->parent.type */
479 srna = (StructRNA *)ptr->data;
480
481 while (srna->base) {
482 iter->level++;
483 srna = srna->base;
484 }
485
486 rna_inheritance_properties_listbase_begin(
487 iter, ptr, &srna->cont.properties, rna_property_builtin);
488}
489
490static PointerRNA rna_Struct_properties_get(CollectionPropertyIterator *iter)
491{
492 ListBaseIterator *internal = &iter->internal.listbase;
493
494 /* we return either PropertyRNA* or IDProperty*, the rna_access.cc
495 * functions can handle both as PropertyRNA* with some tricks */
496 return RNA_pointer_create_discrete(nullptr, &RNA_Property, internal->link);
497}
498
499static void rna_Struct_functions_next(CollectionPropertyIterator *iter)
500{
501 rna_inheritance_functions_listbase_next(iter, rna_function_builtin);
502}
503
504static void rna_Struct_functions_begin(CollectionPropertyIterator *iter, PointerRNA *ptr)
505{
506 StructRNA *srna;
507
508 /* here ptr->data should always be the same as iter->parent.type */
509 srna = (StructRNA *)ptr->data;
510
511 while (srna->base) {
512 iter->level++;
513 srna = srna->base;
514 }
515
516 rna_inheritance_functions_listbase_begin(iter, ptr, &srna->functions, rna_function_builtin);
517}
518
519static PointerRNA rna_Struct_functions_get(CollectionPropertyIterator *iter)
520{
521 ListBaseIterator *internal = &iter->internal.listbase;
522
523 /* we return either PropertyRNA* or IDProperty*, the rna_access.cc
524 * functions can handle both as PropertyRNA* with some tricks */
525 return RNA_pointer_create_discrete(nullptr, &RNA_Function, internal->link);
526}
527
528static void rna_Struct_property_tags_begin(CollectionPropertyIterator *iter, PointerRNA *ptr)
529{
530 /* here ptr->data should always be the same as iter->parent.type */
531 StructRNA *srna = (StructRNA *)ptr->data;
532 const EnumPropertyItem *tag_defines = RNA_struct_property_tag_defines(srna);
533 uint tag_count = tag_defines ? RNA_enum_items_count(tag_defines) : 0;
534
536 iter, ptr, (void *)tag_defines, sizeof(EnumPropertyItem), tag_count, 0, nullptr);
537}
538
539/* Builtin properties iterator re-uses the Struct properties iterator, only
540 * difference is that we need to set the ptr data to the type of the struct
541 * whose properties we want to iterate over. */
542
544{
545 PointerRNA newptr;
546
547 /* we create a new pointer with the type as the data */
548 newptr.type = &RNA_Struct;
549 newptr.data = ptr->type;
550
551 if (ptr->type->flag & STRUCT_ID) {
552 newptr.owner_id = static_cast<ID *>(ptr->data);
553 }
554 else {
555 newptr.owner_id = nullptr;
556 }
557
558 iter->parent = newptr;
559 iter->builtin_parent = *ptr;
560
561 rna_Struct_properties_begin(iter, &newptr);
562}
563
565{
566 rna_Struct_properties_next(iter);
567}
568
570{
571 return rna_Struct_properties_get(iter);
572}
573
575{
576 StructRNA *srna;
577 PropertyRNA *prop;
578
579 srna = ptr->type;
580
581 do {
582 if (srna->cont.prop_lookup_set) {
583 PropertyRNA *const *lookup_prop = srna->cont.prop_lookup_set->lookup_key_ptr_as(key);
584 prop = lookup_prop ? *lookup_prop : nullptr;
585 if (prop) {
586 *r_ptr = {nullptr, &RNA_Property, prop};
587 return true;
588 }
589 }
590 else {
591 for (prop = static_cast<PropertyRNA *>(srna->cont.properties.first); prop; prop = prop->next)
592 {
593 if (!(prop->flag_internal & PROP_INTERN_BUILTIN) && STREQ(prop->identifier, key)) {
594 *r_ptr = {nullptr, &RNA_Property, prop};
595 return true;
596 }
597 }
598 }
599 } while ((srna = srna->base));
600
601 *r_ptr = {};
602 return false;
603}
604
606{
607 return RNA_pointer_create_discrete(nullptr, &RNA_Struct, ptr->type);
608}
609
610/* Property */
611
612static StructRNA *rna_Property_refine(PointerRNA *ptr)
613{
614 PropertyRNA *prop = (PropertyRNA *)ptr->data;
615
616 switch (RNA_property_type(prop)) {
617 case PROP_BOOLEAN:
618 return &RNA_BoolProperty;
619 case PROP_INT:
620 return &RNA_IntProperty;
621 case PROP_FLOAT:
622 return &RNA_FloatProperty;
623 case PROP_STRING:
624 return &RNA_StringProperty;
625 case PROP_ENUM:
626 return &RNA_EnumProperty;
627 case PROP_POINTER:
628 return &RNA_PointerProperty;
629 case PROP_COLLECTION:
630 return &RNA_CollectionProperty;
631 default:
632 return &RNA_Property;
633 }
634}
635
636static void rna_Property_identifier_get(PointerRNA *ptr, char *value)
637{
638 PropertyRNA *prop = (PropertyRNA *)ptr->data;
639 strcpy(value, RNA_property_identifier(prop));
640}
641
642static int rna_Property_identifier_length(PointerRNA *ptr)
643{
644 PropertyRNA *prop = (PropertyRNA *)ptr->data;
645 return strlen(RNA_property_identifier(prop));
646}
647
648static void rna_Property_name_get(PointerRNA *ptr, char *value)
649{
650 PropertyRNA *prop = (PropertyRNA *)ptr->data;
651 const char *name = RNA_property_ui_name_raw(prop);
652 strcpy(value, name ? name : "");
653}
654
655static int rna_Property_name_length(PointerRNA *ptr)
656{
657 PropertyRNA *prop = (PropertyRNA *)ptr->data;
658 const char *name = RNA_property_ui_name_raw(prop);
659 return name ? strlen(name) : 0;
660}
661
662static void rna_Property_description_get(PointerRNA *ptr, char *value)
663{
664 PropertyRNA *prop = (PropertyRNA *)ptr->data;
665 const char *description = RNA_property_ui_description_raw(prop);
666 strcpy(value, description ? description : "");
667}
668static int rna_Property_description_length(PointerRNA *ptr)
669{
670 PropertyRNA *prop = (PropertyRNA *)ptr->data;
671 const char *description = RNA_property_ui_description_raw(prop);
672 return description ? strlen(description) : 0;
673}
674
675static void rna_Property_translation_context_get(PointerRNA *ptr, char *value)
676{
677 PropertyRNA *prop = (PropertyRNA *)ptr->data;
678 strcpy(value, RNA_property_translation_context(prop));
679}
680
681static int rna_Property_translation_context_length(PointerRNA *ptr)
682{
683 PropertyRNA *prop = (PropertyRNA *)ptr->data;
684 return strlen(RNA_property_translation_context(prop));
685}
686
687static int rna_Property_type_get(PointerRNA *ptr)
688{
689 PropertyRNA *prop = (PropertyRNA *)ptr->data;
690 return RNA_property_type(prop);
691}
692
693static int rna_Property_subtype_get(PointerRNA *ptr)
694{
695 PropertyRNA *prop = (PropertyRNA *)ptr->data;
696 return RNA_property_subtype(prop);
697}
698
699static PointerRNA rna_Property_srna_get(PointerRNA *ptr)
700{
701 PropertyRNA *prop = (PropertyRNA *)ptr->data;
702 prop = rna_ensure_property(prop);
703 return RNA_pointer_create_discrete(nullptr, &RNA_Struct, prop->srna);
704}
705
706static int rna_Property_unit_get(PointerRNA *ptr)
707{
708 PropertyRNA *prop = (PropertyRNA *)ptr->data;
709 return RNA_property_unit(prop);
710}
711
712static int rna_Property_icon_get(PointerRNA *ptr)
713{
714 PropertyRNA *prop = (PropertyRNA *)ptr->data;
715 return RNA_property_ui_icon(prop);
716}
717
718static bool rna_Property_readonly_get(PointerRNA *ptr)
719{
720 PropertyRNA *prop = (PropertyRNA *)ptr->data;
721
722 /* don't use this because it will call functions that check the internal
723 * data for introspection we only need to know if it can be edited so the
724 * flag is better for this */
725 // return RNA_property_editable(ptr, prop);
726 return (prop->flag & PROP_EDITABLE) == 0;
727}
728
729static bool rna_Property_animatable_get(PointerRNA *ptr)
730{
731 PropertyRNA *prop = (PropertyRNA *)ptr->data;
732
733 return (prop->flag & PROP_ANIMATABLE) != 0;
734}
735
736static bool rna_Property_overridable_get(PointerRNA *ptr)
737{
738 PropertyRNA *prop = (PropertyRNA *)ptr->data;
739
740 IDProperty *idprop = rna_idproperty_check(&prop, ptr);
741
742 return idprop != nullptr ? (idprop->flag & IDP_FLAG_OVERRIDABLE_LIBRARY) != 0 :
743 (prop->flag_override & PROPOVERRIDE_OVERRIDABLE_LIBRARY) != 0;
744}
745
746static bool rna_Property_use_output_get(PointerRNA *ptr)
747{
748 PropertyRNA *prop = (PropertyRNA *)ptr->data;
749 return (prop->flag_parameter & PARM_OUTPUT) != 0;
750}
751
752static bool rna_Property_is_required_get(PointerRNA *ptr)
753{
754 PropertyRNA *prop = (PropertyRNA *)ptr->data;
755 return (prop->flag_parameter & PARM_REQUIRED) != 0;
756}
757
758static bool rna_Property_is_argument_optional_get(PointerRNA *ptr)
759{
760 PropertyRNA *prop = (PropertyRNA *)ptr->data;
761 return (prop->flag_parameter & PARM_PYFUNC_REGISTER_OPTIONAL) != 0;
762}
763
764static bool rna_Property_is_never_none_get(PointerRNA *ptr)
765{
766 PropertyRNA *prop = (PropertyRNA *)ptr->data;
767 return (prop->flag & PROP_NEVER_NULL) != 0;
768}
769
770static bool rna_Property_is_hidden_get(PointerRNA *ptr)
771{
772 PropertyRNA *prop = (PropertyRNA *)ptr->data;
773 return (prop->flag & PROP_HIDDEN) != 0;
774}
775
776static bool rna_Property_is_skip_save_get(PointerRNA *ptr)
777{
778 PropertyRNA *prop = (PropertyRNA *)ptr->data;
779 return (prop->flag & PROP_SKIP_SAVE) != 0;
780}
781
782static bool rna_Property_is_skip_preset_get(PointerRNA *ptr)
783{
784 PropertyRNA *prop = (PropertyRNA *)ptr->data;
785 return (prop->flag & (PROP_SKIP_SAVE | PROP_HIDDEN | PROP_SKIP_PRESET)) != 0;
786}
787
788static bool rna_Property_is_enum_flag_get(PointerRNA *ptr)
789{
790 PropertyRNA *prop = (PropertyRNA *)ptr->data;
791 return (prop->flag & PROP_ENUM_FLAG) != 0;
792}
793
794static bool rna_Property_is_library_editable_flag_get(PointerRNA *ptr)
795{
796 PropertyRNA *prop = (PropertyRNA *)ptr->data;
797 return (prop->flag & PROP_LIB_EXCEPTION) != 0;
798}
799
800static bool rna_Property_is_path_output_flag_get(PointerRNA *ptr)
801{
802 PropertyRNA *prop = (PropertyRNA *)ptr->data;
803 return (prop->flag & PROP_PATH_OUTPUT) != 0;
804}
805
806static bool rna_Property_is_path_supports_blend_relative_flag_get(PointerRNA *ptr)
807{
808 PropertyRNA *prop = (PropertyRNA *)ptr->data;
809 return (prop->flag & PROP_PATH_SUPPORTS_BLEND_RELATIVE) != 0;
810}
811
812static bool rna_Property_is_path_supports_templates_flag_get(PointerRNA *ptr)
813{
814 PropertyRNA *prop = (PropertyRNA *)ptr->data;
815 return (prop->flag & PROP_PATH_SUPPORTS_TEMPLATES) != 0;
816}
817
818static int rna_Property_tags_get(PointerRNA *ptr)
819{
820 return RNA_property_tags(static_cast<PropertyRNA *>(ptr->data));
821}
822
823static const EnumPropertyItem *rna_Property_tags_itemf(bContext * /*C*/,
825 PropertyRNA * /*prop*/,
826 bool *r_free)
827{
828 PropertyRNA *this_prop = (PropertyRNA *)ptr->data;
829 const StructRNA *srna = RNA_property_pointer_type(ptr, this_prop);
830 EnumPropertyItem *prop_tags;
831 EnumPropertyItem tmp = {0, "", 0, "", ""};
832 int totitem = 0;
833
834 for (const EnumPropertyItem *struct_tags = RNA_struct_property_tag_defines(srna);
835 struct_tags != nullptr && struct_tags->identifier != nullptr;
836 struct_tags++)
837 {
838 memcpy(&tmp, struct_tags, sizeof(tmp));
839 RNA_enum_item_add(&prop_tags, &totitem, &tmp);
840 }
841 RNA_enum_item_end(&prop_tags, &totitem);
842 *r_free = true;
843
844 return prop_tags;
845}
846
847static int rna_Property_array_length_get(PointerRNA *ptr)
848{
849 PropertyRNA *prop = (PropertyRNA *)ptr->data;
850 prop = rna_ensure_property(prop);
851 return prop->totarraylength;
852}
853
854static void rna_Property_array_dimensions_get(PointerRNA *ptr,
855 int dimensions[RNA_MAX_ARRAY_DIMENSION])
856{
857 PropertyRNA *prop = (PropertyRNA *)ptr->data;
858 prop = rna_ensure_property(prop);
859
860 if (prop->arraydimension > 1) {
861 for (int i = RNA_MAX_ARRAY_DIMENSION; i--;) {
862 dimensions[i] = (i >= prop->arraydimension) ? 0 : prop->arraylength[i];
863 }
864 }
865 else {
866 memset(dimensions, 0, sizeof(*dimensions) * RNA_MAX_ARRAY_DIMENSION);
867 dimensions[0] = prop->totarraylength;
868 }
869}
870
871static bool rna_Property_is_registered_get(PointerRNA *ptr)
872{
873 PropertyRNA *prop = (PropertyRNA *)ptr->data;
874 return (prop->flag & PROP_REGISTER) != 0;
875}
876
877static bool rna_Property_is_registered_optional_get(PointerRNA *ptr)
878{
879 PropertyRNA *prop = (PropertyRNA *)ptr->data;
880 return (prop->flag & PROP_REGISTER_OPTIONAL) != 0;
881}
882
883static bool rna_Property_is_runtime_get(PointerRNA *ptr)
884{
885 PropertyRNA *prop = (PropertyRNA *)ptr->data;
886 return RNA_property_is_runtime(prop);
887}
888
889static bool rna_BoolProperty_default_get(PointerRNA *ptr)
890{
891 PropertyRNA *prop = (PropertyRNA *)ptr->data;
892 prop = rna_ensure_property(prop);
893 return ((BoolPropertyRNA *)prop)->defaultvalue;
894}
895
896static int rna_IntProperty_default_get(PointerRNA *ptr)
897{
898 PropertyRNA *prop = (PropertyRNA *)ptr->data;
899 prop = rna_ensure_property(prop);
900 return ((IntPropertyRNA *)prop)->defaultvalue;
901}
902/* int/float/bool */
903static int rna_NumberProperty_default_array_get_length(const PointerRNA *ptr,
905{
906 PropertyRNA *prop = (PropertyRNA *)ptr->data;
907 prop = rna_ensure_property(prop);
908
909 length[0] = prop->totarraylength;
910
911 return length[0];
912}
913static bool rna_NumberProperty_is_array_get(PointerRNA *ptr)
914{
915 PropertyRNA *prop = (PropertyRNA *)ptr->data;
916
917 return RNA_property_array_check(prop);
918}
919
920static void rna_IntProperty_default_array_get(PointerRNA *ptr, int *values)
921{
922 PropertyRNA *prop = (PropertyRNA *)ptr->data;
923 prop = rna_ensure_property(prop);
924 if (prop->totarraylength > 0) {
925 PointerRNA null_ptr = PointerRNA_NULL;
926 RNA_property_int_get_default_array(&null_ptr, prop, values);
927 }
928}
929
930static void rna_BoolProperty_default_array_get(PointerRNA *ptr, bool *values)
931{
932 PropertyRNA *prop = (PropertyRNA *)ptr->data;
933 prop = rna_ensure_property(prop);
934 if (prop->totarraylength > 0) {
935 PointerRNA null_ptr = PointerRNA_NULL;
936 RNA_property_boolean_get_default_array(&null_ptr, prop, values);
937 }
938}
939
940static void rna_FloatProperty_default_array_get(PointerRNA *ptr, float *values)
941{
942 PropertyRNA *prop = (PropertyRNA *)ptr->data;
943 prop = rna_ensure_property(prop);
944 if (prop->totarraylength > 0) {
945 PointerRNA null_ptr = PointerRNA_NULL;
946 RNA_property_float_get_default_array(&null_ptr, prop, values);
947 }
948}
949
950static int rna_IntProperty_hard_min_get(PointerRNA *ptr)
951{
952 PropertyRNA *prop = (PropertyRNA *)ptr->data;
953 prop = rna_ensure_property(prop);
954 return ((IntPropertyRNA *)prop)->hardmin;
955}
956
957static int rna_IntProperty_hard_max_get(PointerRNA *ptr)
958{
959 PropertyRNA *prop = (PropertyRNA *)ptr->data;
960 prop = rna_ensure_property(prop);
961 return ((IntPropertyRNA *)prop)->hardmax;
962}
963
964static int rna_IntProperty_soft_min_get(PointerRNA *ptr)
965{
966 PropertyRNA *prop = (PropertyRNA *)ptr->data;
967 prop = rna_ensure_property(prop);
968 return ((IntPropertyRNA *)prop)->softmin;
969}
970
971static int rna_IntProperty_soft_max_get(PointerRNA *ptr)
972{
973 PropertyRNA *prop = (PropertyRNA *)ptr->data;
974 prop = rna_ensure_property(prop);
975 return ((IntPropertyRNA *)prop)->softmax;
976}
977
978static int rna_IntProperty_step_get(PointerRNA *ptr)
979{
980 PropertyRNA *prop = (PropertyRNA *)ptr->data;
981 prop = rna_ensure_property(prop);
982 return ((IntPropertyRNA *)prop)->step;
983}
984
985static float rna_FloatProperty_default_get(PointerRNA *ptr)
986{
987 PropertyRNA *prop = (PropertyRNA *)ptr->data;
988 prop = rna_ensure_property(prop);
989 return ((FloatPropertyRNA *)prop)->defaultvalue;
990}
991static float rna_FloatProperty_hard_min_get(PointerRNA *ptr)
992{
993 PropertyRNA *prop = (PropertyRNA *)ptr->data;
994 prop = rna_ensure_property(prop);
995 return ((FloatPropertyRNA *)prop)->hardmin;
996}
997
998static float rna_FloatProperty_hard_max_get(PointerRNA *ptr)
999{
1000 PropertyRNA *prop = (PropertyRNA *)ptr->data;
1001 prop = rna_ensure_property(prop);
1002 return ((FloatPropertyRNA *)prop)->hardmax;
1003}
1004
1005static float rna_FloatProperty_soft_min_get(PointerRNA *ptr)
1006{
1007 PropertyRNA *prop = (PropertyRNA *)ptr->data;
1008 prop = rna_ensure_property(prop);
1009 return ((FloatPropertyRNA *)prop)->softmin;
1010}
1011
1012static float rna_FloatProperty_soft_max_get(PointerRNA *ptr)
1013{
1014 PropertyRNA *prop = (PropertyRNA *)ptr->data;
1015 prop = rna_ensure_property(prop);
1016 return ((FloatPropertyRNA *)prop)->softmax;
1017}
1018
1019static float rna_FloatProperty_step_get(PointerRNA *ptr)
1020{
1021 PropertyRNA *prop = (PropertyRNA *)ptr->data;
1022 prop = rna_ensure_property(prop);
1023 return ((FloatPropertyRNA *)prop)->step;
1024}
1025
1026static int rna_FloatProperty_precision_get(PointerRNA *ptr)
1027{
1028 PropertyRNA *prop = (PropertyRNA *)ptr->data;
1029 prop = rna_ensure_property(prop);
1030 return ((FloatPropertyRNA *)prop)->precision;
1031}
1032
1033static void rna_StringProperty_default_get(PointerRNA *ptr, char *value)
1034{
1035 PropertyRNA *prop = (PropertyRNA *)ptr->data;
1036 prop = rna_ensure_property(prop);
1037 strcpy(value, ((StringPropertyRNA *)prop)->defaultvalue);
1038}
1039static int rna_StringProperty_default_length(PointerRNA *ptr)
1040{
1041 PropertyRNA *prop = (PropertyRNA *)ptr->data;
1042 prop = rna_ensure_property(prop);
1043 return strlen(((StringPropertyRNA *)prop)->defaultvalue);
1044}
1045
1046static int rna_StringProperty_max_length_get(PointerRNA *ptr)
1047{
1048 PropertyRNA *prop = (PropertyRNA *)ptr->data;
1049 prop = rna_ensure_property(prop);
1050 return ((StringPropertyRNA *)prop)->maxlength;
1051}
1052
1053static const EnumPropertyItem *rna_EnumProperty_default_itemf(bContext *C,
1054 PointerRNA *ptr,
1055 PropertyRNA *prop_parent,
1056 bool *r_free)
1057{
1058 PropertyRNA *prop = (PropertyRNA *)ptr->data;
1059 EnumPropertyRNA *eprop;
1060
1061 prop = rna_ensure_property(prop);
1062 eprop = (EnumPropertyRNA *)prop;
1063
1064 /* incompatible default attributes */
1065 if ((prop_parent->flag & PROP_ENUM_FLAG) != (prop->flag & PROP_ENUM_FLAG)) {
1067 }
1068
1069 if ((eprop->item_fn == nullptr) || (eprop->item_fn == rna_EnumProperty_default_itemf) ||
1070 (ptr->type == &RNA_EnumProperty) || (C == nullptr))
1071 {
1072 if (eprop->item) {
1073 return eprop->item;
1074 }
1075 }
1076
1077 return eprop->item_fn(C, ptr, prop, r_free);
1078}
1079
1080/* XXX: not sure this is needed? */
1081static int rna_EnumProperty_default_get(PointerRNA *ptr)
1082{
1083 PropertyRNA *prop = (PropertyRNA *)ptr->data;
1084 prop = rna_ensure_property(prop);
1085 return ((EnumPropertyRNA *)prop)->defaultvalue;
1086}
1087
1088static bool rna_enum_check_separator(CollectionPropertyIterator * /*iter*/, void *data)
1089{
1091
1092 return (item->identifier[0] == 0);
1093}
1094
1095static void rna_EnumProperty_items_begin_impl(CollectionPropertyIterator *iter,
1096 PointerRNA *ptr,
1097 IteratorSkipFunc skip_fn)
1098{
1099 PropertyRNA *prop = (PropertyRNA *)ptr->data;
1100 // EnumPropertyRNA *eprop; /* UNUSED */
1101 const EnumPropertyItem *item = nullptr;
1102 int totitem;
1103 bool free;
1104
1105 prop = rna_ensure_property(prop);
1106 // eprop = (EnumPropertyRNA *)prop;
1107
1109 ptr,
1110 prop,
1111 STREQ(iter->prop->identifier, "enum_items_static"),
1112 &item,
1113 &totitem,
1114 &free);
1116 iter, ptr, (void *)item, sizeof(EnumPropertyItem), totitem, free, skip_fn);
1117}
1118
1119static void rna_EnumProperty_items_begin(CollectionPropertyIterator *iter, PointerRNA *ptr)
1120{
1121 rna_EnumProperty_items_begin_impl(iter, ptr, rna_enum_check_separator);
1122}
1123
1124static void rna_EnumProperty_items_ui_begin(CollectionPropertyIterator *iter, PointerRNA *ptr)
1125{
1126 /* No skip-function, include all "UI" items. */
1127 rna_EnumProperty_items_begin_impl(iter, ptr, nullptr);
1128}
1129
1130static void rna_EnumPropertyItem_identifier_get(PointerRNA *ptr, char *value)
1131{
1132 strcpy(value, ((EnumPropertyItem *)ptr->data)->identifier);
1133}
1134
1135static int rna_EnumPropertyItem_identifier_length(PointerRNA *ptr)
1136{
1137 return strlen(((EnumPropertyItem *)ptr->data)->identifier);
1138}
1139
1140static void rna_EnumPropertyItem_name_get(PointerRNA *ptr, char *value)
1141{
1142 const EnumPropertyItem *eprop = static_cast<const EnumPropertyItem *>(ptr->data);
1143 /* Name can be nullptr in the case of separators
1144 * which are exposed via `_bpy.rna_enum_items_static`. */
1145 if (eprop->name) {
1146 strcpy(value, eprop->name);
1147 }
1148 else {
1149 value[0] = '\0';
1150 }
1151}
1152
1153static int rna_EnumPropertyItem_name_length(PointerRNA *ptr)
1154{
1155 const EnumPropertyItem *eprop = static_cast<const EnumPropertyItem *>(ptr->data);
1156 if (eprop->name) {
1157 return strlen(eprop->name);
1158 }
1159 return 0;
1160}
1161
1162static void rna_EnumPropertyItem_description_get(PointerRNA *ptr, char *value)
1163{
1164 const EnumPropertyItem *eprop = static_cast<const EnumPropertyItem *>(ptr->data);
1165
1166 if (eprop->description) {
1167 strcpy(value, eprop->description);
1168 }
1169 else {
1170 value[0] = '\0';
1171 }
1172}
1173
1174static int rna_EnumPropertyItem_description_length(PointerRNA *ptr)
1175{
1176 EnumPropertyItem *eprop = (EnumPropertyItem *)ptr->data;
1177
1178 if (eprop->description) {
1179 return strlen(eprop->description);
1180 }
1181 return 0;
1182}
1183
1184static int rna_EnumPropertyItem_value_get(PointerRNA *ptr)
1185{
1186 return ((EnumPropertyItem *)ptr->data)->value;
1187}
1188
1189static int rna_EnumPropertyItem_icon_get(PointerRNA *ptr)
1190{
1191 return ((EnumPropertyItem *)ptr->data)->icon;
1192}
1193
1194static PointerRNA rna_PointerProperty_fixed_type_get(PointerRNA *ptr)
1195{
1196 PropertyRNA *prop = (PropertyRNA *)ptr->data;
1197 prop = rna_ensure_property(prop);
1198 return RNA_pointer_create_discrete(nullptr, &RNA_Struct, ((PointerPropertyRNA *)prop)->type);
1199}
1200
1201static PointerRNA rna_CollectionProperty_fixed_type_get(PointerRNA *ptr)
1202{
1203 PropertyRNA *prop = (PropertyRNA *)ptr->data;
1204 prop = rna_ensure_property(prop);
1206 nullptr, &RNA_Struct, ((CollectionPropertyRNA *)prop)->item_type);
1207}
1208
1209/* Function */
1210
1211static void rna_Function_identifier_get(PointerRNA *ptr, char *value)
1212{
1213 strcpy(value, ((FunctionRNA *)ptr->data)->identifier);
1214}
1215
1216static int rna_Function_identifier_length(PointerRNA *ptr)
1217{
1218 return strlen(((FunctionRNA *)ptr->data)->identifier);
1219}
1220
1221static void rna_Function_description_get(PointerRNA *ptr, char *value)
1222{
1223 strcpy(value, ((FunctionRNA *)ptr->data)->description);
1224}
1225
1226static int rna_Function_description_length(PointerRNA *ptr)
1227{
1228 return strlen(((FunctionRNA *)ptr->data)->description);
1229}
1230
1231static void rna_Function_parameters_begin(CollectionPropertyIterator *iter, PointerRNA *ptr)
1232{
1234 iter, ptr, &((FunctionRNA *)ptr->data)->cont.properties, rna_property_builtin);
1235}
1236
1237static bool rna_Function_registered_get(PointerRNA *ptr)
1238{
1239 FunctionRNA *func = (FunctionRNA *)ptr->data;
1240 return 0 != (func->flag & FUNC_REGISTER);
1241}
1242
1243static bool rna_Function_registered_optional_get(PointerRNA *ptr)
1244{
1245 FunctionRNA *func = (FunctionRNA *)ptr->data;
1246 return 0 != (func->flag & (FUNC_REGISTER_OPTIONAL & ~FUNC_REGISTER));
1247}
1248
1249static bool rna_Function_no_self_get(PointerRNA *ptr)
1250{
1251 FunctionRNA *func = (FunctionRNA *)ptr->data;
1252 return !(func->flag & FUNC_NO_SELF);
1253}
1254
1255static bool rna_Function_use_self_type_get(PointerRNA *ptr)
1256{
1257 FunctionRNA *func = (FunctionRNA *)ptr->data;
1258 return 0 != (func->flag & FUNC_USE_SELF_TYPE);
1259}
1260
1261/* Blender RNA */
1262
1263static bool rna_struct_is_publc(CollectionPropertyIterator * /*iter*/, void *data)
1264{
1265 StructRNA *srna = static_cast<StructRNA *>(data);
1266
1267 return !(srna->flag & STRUCT_PUBLIC_NAMESPACE);
1268}
1269
1270static void rna_BlenderRNA_structs_begin(CollectionPropertyIterator *iter, PointerRNA *ptr)
1271{
1272 BlenderRNA *brna = static_cast<BlenderRNA *>(ptr->data);
1273 rna_iterator_listbase_begin(iter, ptr, &brna->structs, rna_struct_is_publc);
1274}
1275
1276/* optional, for faster lookups */
1277static int rna_BlenderRNA_structs_length(PointerRNA *ptr)
1278{
1279 BlenderRNA *brna = static_cast<BlenderRNA *>(ptr->data);
1281 return brna->structs_len;
1282}
1283static bool rna_BlenderRNA_structs_lookup_int(PointerRNA *ptr, int index, PointerRNA *r_ptr)
1284{
1285 BlenderRNA *brna = static_cast<BlenderRNA *>(ptr->data);
1286 StructRNA *srna = static_cast<StructRNA *>(
1287 index < brna->structs_len ? BLI_findlink(&brna->structs, index) : nullptr);
1288 if (srna != nullptr) {
1289 *r_ptr = RNA_pointer_create_discrete(nullptr, &RNA_Struct, srna);
1290 return true;
1291 }
1292 else {
1293 return false;
1294 }
1295}
1296static bool rna_BlenderRNA_structs_lookup_string(PointerRNA *ptr,
1297 const char *key,
1298 PointerRNA *r_ptr)
1299{
1300 BlenderRNA *brna = static_cast<BlenderRNA *>(ptr->data);
1301 StructRNA *srna = static_cast<StructRNA *>(BLI_ghash_lookup(brna->structs_map, (void *)key));
1302 if (srna != nullptr) {
1303 *r_ptr = RNA_pointer_create_discrete(nullptr, &RNA_Struct, srna);
1304 return true;
1305 }
1306
1307 return false;
1308}
1309
1310/* Default override (and compare) callbacks. */
1311
1316struct RNACompareOverrideDiffPropPtrContext {
1318 RNAPropertyOverrideDiffContext &rnadiff_ctx;
1319
1321 ID *owner_id_a = nullptr;
1322 ID *owner_id_b = nullptr;
1323 PointerRNA propptr_a = {};
1324 PointerRNA propptr_b = {};
1325 PropertyType property_type = PROP_BOOLEAN;
1326
1331 bool no_ownership = false;
1336 bool no_prop_name = false;
1339 bool do_force_name = false;
1341 bool use_id_pointer = false;
1342
1352 bool has_liboverride_apply_cb = false;
1353
1355 /* NOTE: names (and ID pointers, in case items are ID pointers) are typically set by a call
1356 * to #rna_property_override_diff_propptr_validate_diffing. Indices are typically set directly
1357 * from the loop over all RNA collections items in #rna_property_override_diff_default. */
1358 std::optional<std::string> rna_itemname_a;
1359 std::optional<std::string> rna_itemname_b;
1360 std::optional<ID *> rna_itemid_a;
1361 std::optional<ID *> rna_itemid_b;
1362 int rna_itemindex_a = -1;
1363 int rna_itemindex_b = -1;
1364
1372 bool is_valid_for_diffing = true;
1373
1374 bool is_id = false;
1375 bool is_null = false;
1376 bool is_type_diff = false;
1377
1378 RNACompareOverrideDiffPropPtrContext(RNAPropertyOverrideDiffContext &rnadiff_ctx_)
1379 : rnadiff_ctx(rnadiff_ctx_)
1380 {
1381 }
1382};
1383static void rna_property_override_diff_propptr_validate_diffing(
1384 RNACompareOverrideDiffPropPtrContext &ptrdiff_ctx)
1385{
1386 PointerRNA *propptr_a = &ptrdiff_ctx.propptr_a;
1387 PointerRNA *propptr_b = &ptrdiff_ctx.propptr_b;
1388 const bool no_ownership = ptrdiff_ctx.no_ownership;
1389 const bool no_prop_name = ptrdiff_ctx.no_prop_name;
1390 const bool do_force_name = ptrdiff_ctx.do_force_name;
1391
1392 ptrdiff_ctx.is_valid_for_diffing = true;
1393
1394 BLI_assert(propptr_a != nullptr);
1395
1396 if (do_force_name || ptrdiff_ctx.use_id_pointer) {
1397 BLI_assert(!no_prop_name);
1398 }
1399
1400 /* Beware, PointerRNA_NULL has no type and is considered a 'blank page'! */
1401 if (ELEM(nullptr, propptr_a->type, propptr_a->data)) {
1402 if (ELEM(nullptr, propptr_b, propptr_b->type, propptr_b->data)) {
1403 ptrdiff_ctx.is_null = true;
1404 }
1405 else {
1406 ptrdiff_ctx.is_id = RNA_struct_is_ID(propptr_b->type);
1407 ptrdiff_ctx.is_null = true;
1408 ptrdiff_ctx.is_type_diff = propptr_a->type != propptr_b->type;
1409 }
1410 ptrdiff_ctx.is_valid_for_diffing = false;
1411 }
1412 else {
1413 ptrdiff_ctx.is_id = RNA_struct_is_ID(propptr_a->type);
1414 ptrdiff_ctx.is_null = (ELEM(nullptr, propptr_b, propptr_b->type, propptr_b->data));
1415 ptrdiff_ctx.is_type_diff = (propptr_b == nullptr || propptr_b->type != propptr_a->type);
1416 ptrdiff_ctx.is_valid_for_diffing = !((ptrdiff_ctx.is_id && no_ownership) ||
1417 ptrdiff_ctx.is_null || ptrdiff_ctx.is_type_diff);
1418 }
1419
1420 /* We do a generic quick first comparison checking for "name" and/or "type" properties.
1421 * We assume that is any of those are false, then we are not handling the same data.
1422 * This helps a lot in library override case, especially to detect inserted items in collections.
1423 */
1424 if (!no_prop_name && (ptrdiff_ctx.is_valid_for_diffing || do_force_name)) {
1425 PropertyRNA *nameprop_a = (propptr_a->type != nullptr) ?
1426 RNA_struct_name_property(propptr_a->type) :
1427 nullptr;
1428 PropertyRNA *nameprop_b = (propptr_b != nullptr && propptr_b->type != nullptr) ?
1429 RNA_struct_name_property(propptr_b->type) :
1430 nullptr;
1431 const bool do_id_pointer = ptrdiff_ctx.use_id_pointer && ptrdiff_ctx.is_id;
1432
1433 /* NOTE: Until we have a `std::string` version of `RNA_property_string_get`, these C string
1434 * pointers and buffers are needed here. Otherwise, in case of C string allocation, if the
1435 * result of `RNA_property_string_get` is directly assigned to a `std::string`, there is no way
1436 * to free this memory. */
1437 int rna_itemname_a_len = 0, rna_itemname_b_len = 0;
1438 char *rna_itemname_a = nullptr;
1439 char *rna_itemname_b = nullptr;
1440 char buff_a[4096];
1441 char buff_b[4096];
1442 if (nameprop_a != nullptr) {
1443 rna_itemname_a = RNA_property_string_get_alloc(
1444 propptr_a, nameprop_a, buff_a, sizeof(buff_a), &rna_itemname_a_len);
1445 // printf("rna_itemname_a = %s\n", rna_itemname_a ? rna_itemname_a : "<NONE>");
1446 ptrdiff_ctx.rna_itemname_a = rna_itemname_a;
1447 }
1448 // else printf("item of type %s a has no name property!\n", propptr_a->type->name);
1449 if (nameprop_b != nullptr) {
1450 rna_itemname_b = RNA_property_string_get_alloc(
1451 propptr_b, nameprop_b, buff_b, sizeof(buff_b), &rna_itemname_b_len);
1452 ptrdiff_ctx.rna_itemname_b = rna_itemname_b;
1453 }
1454
1455 /* NOTE: This will always assign nullptr to these lib-pointers in case `do_id_lib` is false,
1456 * which ensures that they will not affect the result of `ptrdiff_ctx.is_valid_for_diffing` in
1457 * the last check below. */
1458 ID *rna_itemid_a = (do_id_pointer && propptr_a->data) ? static_cast<ID *>(propptr_a->data) :
1459 nullptr;
1460 ID *rna_itemid_b = (do_id_pointer && propptr_b->data) ? static_cast<ID *>(propptr_b->data) :
1461 nullptr;
1462 if (do_id_pointer) {
1463 ptrdiff_ctx.rna_itemid_a = rna_itemid_a;
1464 ptrdiff_ctx.rna_itemid_b = rna_itemid_b;
1465 }
1466
1467 if (rna_itemname_a != nullptr && rna_itemname_b != nullptr) {
1468 if (rna_itemid_a != rna_itemid_b || rna_itemname_a_len != rna_itemname_b_len ||
1469 rna_itemname_a[0] != rna_itemname_b[0] || !STREQ(rna_itemname_a, rna_itemname_b))
1470 {
1471 ptrdiff_ctx.is_valid_for_diffing = false;
1472 // printf("%s: different names\n", rna_path ? rna_path : "<UNKNOWN>");
1473 }
1474 }
1475 if (UNLIKELY(rna_itemname_a && rna_itemname_a != buff_a)) {
1476 MEM_freeN(rna_itemname_a);
1477 }
1478 if (UNLIKELY(rna_itemname_b && rna_itemname_b != buff_b)) {
1479 MEM_freeN(rna_itemname_b);
1480 }
1481 }
1482
1483 if (ptrdiff_ctx.is_id) {
1484 BLI_assert(propptr_a->data == propptr_a->owner_id && propptr_b->data == propptr_b->owner_id);
1485 }
1486}
1487
1488/* Used for both Pointer and Collection properties. */
1489static void rna_property_override_diff_propptr(Main *bmain,
1490 RNACompareOverrideDiffPropPtrContext &ptrdiff_ctx)
1491{
1492 ID *owner_id_a = ptrdiff_ctx.owner_id_a;
1493 ID *owner_id_b = ptrdiff_ctx.owner_id_b;
1494 PointerRNA *propptr_a = &ptrdiff_ctx.propptr_a;
1495 PointerRNA *propptr_b = &ptrdiff_ctx.propptr_b;
1496
1497 eRNACompareMode mode = ptrdiff_ctx.rnadiff_ctx.mode;
1498 const bool no_ownership = ptrdiff_ctx.no_ownership;
1499
1500 IDOverrideLibrary *liboverride = ptrdiff_ctx.rnadiff_ctx.liboverride;
1501 const eRNAOverrideMatch liboverride_flags = ptrdiff_ctx.rnadiff_ctx.liboverride_flags;
1502 const char *rna_path = ptrdiff_ctx.rnadiff_ctx.rna_path;
1503 size_t rna_path_len = ptrdiff_ctx.rnadiff_ctx.rna_path_len;
1504 const PropertyType property_type = ptrdiff_ctx.property_type;
1505
1506 std::optional<std::string> &rna_itemname_a = ptrdiff_ctx.rna_itemname_a;
1507 std::optional<std::string> &rna_itemname_b = ptrdiff_ctx.rna_itemname_b;
1508 const int rna_itemindex_a = ptrdiff_ctx.rna_itemindex_a;
1509 const int rna_itemindex_b = ptrdiff_ctx.rna_itemindex_b;
1510
1511 BLI_assert(ELEM(property_type, PROP_POINTER, PROP_COLLECTION));
1512
1513 rna_property_override_diff_propptr_validate_diffing(ptrdiff_ctx);
1514
1515 /* If false, it means that the whole data itself is different,
1516 * so no point in going inside of it at all! */
1517 const bool is_valid_for_diffing = ptrdiff_ctx.is_valid_for_diffing;
1518 const bool is_id = ptrdiff_ctx.is_id;
1519 const bool is_null = ptrdiff_ctx.is_null;
1520 const bool is_type_diff = ptrdiff_ctx.is_type_diff;
1521
1522 const bool has_liboverride_apply_cb = ptrdiff_ctx.has_liboverride_apply_cb;
1523 const bool do_create = (liboverride != nullptr &&
1524 /* Replacing a Pointer can only happen if it's an ID one, or there is a
1525 * dedicated apply callback defined for the property. */
1526 (is_id || has_liboverride_apply_cb) &&
1527 (liboverride_flags & RNA_OVERRIDE_COMPARE_CREATE) != 0 &&
1528 rna_path != nullptr);
1529
1530 if (is_id) {
1531 /* Owned IDs (the ones we want to actually compare in depth, instead of just comparing pointer
1532 * values) should be always properly tagged as 'virtual' overrides. */
1533 ID *id = propptr_a->owner_id;
1534 if (id != nullptr && !ID_IS_OVERRIDE_LIBRARY(id)) {
1535 id = propptr_b->owner_id;
1536 if (id != nullptr && !ID_IS_OVERRIDE_LIBRARY(id)) {
1537 id = nullptr;
1538 }
1539 }
1540
1541 BLI_assert(no_ownership || id == nullptr || ID_IS_OVERRIDE_LIBRARY_VIRTUAL(id));
1543 }
1544
1545 if (liboverride) {
1546 if (no_ownership || is_null || is_type_diff || !is_valid_for_diffing) {
1547 /* In case this pointer prop does not own its data (or one is nullptr), do not compare
1548 * structs! This is a quite safe path to infinite loop, among other nasty issues. Instead,
1549 * just compare pointers themselves. */
1550 ptrdiff_ctx.rnadiff_ctx.comparison = (propptr_a->data != propptr_b->data);
1551
1552 if (do_create && ptrdiff_ctx.rnadiff_ctx.comparison != 0) {
1553 bool created = false;
1555 liboverride, rna_path, &created);
1556
1557 /* If not yet overridden, or if we are handling sub-items (inside a collection)... */
1558 if (op != nullptr) {
1559 if (created || op->rna_prop_type == 0) {
1560 op->rna_prop_type = property_type;
1561 }
1562 else {
1563 BLI_assert(op->rna_prop_type == property_type);
1564 }
1565
1566 IDOverrideLibraryPropertyOperation *opop = nullptr;
1567 if (created || (rna_itemname_a && !rna_itemname_a->empty()) ||
1568 (rna_itemname_b && !rna_itemname_b->empty()) || rna_itemindex_a != -1 ||
1569 rna_itemindex_b != -1)
1570 {
1571 const char *subitem_refname = rna_itemname_b ? rna_itemname_b->c_str() : nullptr;
1572 const char *subitem_locname = rna_itemname_a ? rna_itemname_a->c_str() : nullptr;
1575 subitem_refname,
1576 subitem_locname,
1577 ptrdiff_ctx.rna_itemid_b,
1578 ptrdiff_ctx.rna_itemid_a,
1579 rna_itemindex_b,
1580 rna_itemindex_a,
1581 true,
1582 nullptr,
1583 &created);
1584 /* Do not use BKE_lib_override_library_operations_tag here, we do not want to validate
1585 * as used all of its operations. */
1588 if (created) {
1589 ptrdiff_ctx.rnadiff_ctx.report_flag |= RNA_OVERRIDE_MATCH_RESULT_CREATED;
1590 }
1591 }
1592 else {
1594 }
1595
1596 if (is_id && no_ownership) {
1597 if (opop == nullptr) {
1598 const char *subitem_refname = rna_itemname_b ? rna_itemname_b->c_str() : nullptr;
1599 const char *subitem_locname = rna_itemname_a ? rna_itemname_a->c_str() : nullptr;
1602 subitem_refname,
1603 subitem_locname,
1604 ptrdiff_ctx.rna_itemid_b,
1605 ptrdiff_ctx.rna_itemid_a,
1606 rna_itemindex_b,
1607 rna_itemindex_a,
1608 true,
1609 nullptr,
1610 &created);
1611 /* Do not use BKE_lib_override_library_operations_tag here, we do not want to
1612 * validate as used all of its operations. */
1615 if (created) {
1616 ptrdiff_ctx.rnadiff_ctx.report_flag |= RNA_OVERRIDE_MATCH_RESULT_CREATED;
1617 }
1618 }
1619
1620 BLI_assert(propptr_a->data == propptr_a->owner_id);
1621 BLI_assert(propptr_b->data == propptr_b->owner_id);
1622 ID *id_a = static_cast<ID *>(propptr_a->data);
1623 ID *id_b = static_cast<ID *>(propptr_b->data);
1624 if (ELEM(nullptr, id_a, id_b)) {
1625 /* In case one of the pointer is nullptr and not the other, we consider that the
1626 * liboverride is not matching its reference anymore. */
1628 }
1629 else if ((owner_id_a->tag & ID_TAG_LIBOVERRIDE_NEED_RESYNC) != 0 ||
1630 (owner_id_b->tag & ID_TAG_LIBOVERRIDE_NEED_RESYNC) != 0)
1631 {
1632 /* In case one of the owner of the checked property is tagged as needing resync, do
1633 * not change the 'match reference' status of its ID pointer properties overrides,
1634 * since many non-matching ones are likely due to missing resync. */
1635 CLOG_INFO(&LOG_COMPARE_OVERRIDE,
1636 4,
1637 "Not checking matching ID pointer properties, since owner %s is tagged as "
1638 "needing resync.\n",
1639 id_a->name);
1640 }
1641 else if (id_a->override_library != nullptr &&
1642 id_a->override_library->reference == id_b)
1643 {
1645 }
1646 else if (id_b->override_library != nullptr &&
1647 id_b->override_library->reference == id_a)
1648 {
1650 }
1651 else {
1653 }
1654 }
1655 }
1656 }
1657 }
1658 else {
1659/* In case we got some array/collection like items identifiers, now is the time to generate a
1660 * proper rna path from those. */
1661# define RNA_PATH_BUFFSIZE 8192
1662
1663 char extended_rna_path_buffer[RNA_PATH_BUFFSIZE];
1664 char *extended_rna_path = extended_rna_path_buffer;
1665 size_t extended_rna_path_len = 0;
1666
1667 /* There may be a propname defined in some cases, while no actual name set
1668 * (e.g. happens with point cache), in that case too we want to fall back to index.
1669 * Note that we do not need the RNA path for insertion operations. */
1670 if (rna_path) {
1671 if ((rna_itemname_a && !rna_itemname_a->empty()) &&
1672 (rna_itemname_b && !rna_itemname_b->empty()))
1673 {
1674 BLI_assert(*rna_itemname_a == *rna_itemname_b);
1675
1676 char esc_item_name[RNA_PATH_BUFFSIZE];
1677 const size_t esc_item_name_len = BLI_str_escape(
1678 esc_item_name, rna_itemname_a->c_str(), sizeof(esc_item_name));
1679 extended_rna_path_len = rna_path_len + 2 + esc_item_name_len + 2;
1680 if (extended_rna_path_len >= RNA_PATH_BUFFSIZE) {
1681 extended_rna_path = MEM_malloc_arrayN<char>(extended_rna_path_len + 1, __func__);
1682 }
1683
1684 memcpy(extended_rna_path, rna_path, rna_path_len);
1685 extended_rna_path[rna_path_len] = '[';
1686 extended_rna_path[rna_path_len + 1] = '"';
1687 memcpy(extended_rna_path + rna_path_len + 2, esc_item_name, esc_item_name_len);
1688 extended_rna_path[rna_path_len + 2 + esc_item_name_len] = '"';
1689 extended_rna_path[rna_path_len + 2 + esc_item_name_len + 1] = ']';
1690 extended_rna_path[extended_rna_path_len] = '\0';
1691 }
1692 else if (rna_itemindex_a != -1) { /* Based on index... */
1693 BLI_assert(rna_itemindex_a == rna_itemindex_b);
1694
1695 /* low-level specific highly-efficient conversion of positive integer to string. */
1696 char item_index_buff[32];
1697 size_t item_index_buff_len = 0;
1698 if (rna_itemindex_a == 0) {
1699 item_index_buff[0] = '0';
1700 item_index_buff_len = 1;
1701 }
1702 else {
1703 uint index;
1704 for (index = rna_itemindex_a;
1705 index > 0 && item_index_buff_len < sizeof(item_index_buff);
1706 index /= 10)
1707 {
1708 item_index_buff[item_index_buff_len++] = '0' + char(index % 10);
1709 }
1710 BLI_assert(index == 0);
1711 }
1712
1713 extended_rna_path_len = rna_path_len + item_index_buff_len + 2;
1714 if (extended_rna_path_len >= RNA_PATH_BUFFSIZE) {
1715 extended_rna_path = MEM_malloc_arrayN<char>(extended_rna_path_len + 1, __func__);
1716 }
1717
1718 memcpy(extended_rna_path, rna_path, rna_path_len);
1719 extended_rna_path[rna_path_len] = '[';
1720 for (size_t i = 1; i <= item_index_buff_len; i++) {
1721 /* The first loop above generated inverted string representation of our index number.
1722 */
1723 extended_rna_path[rna_path_len + i] = item_index_buff[item_index_buff_len - i];
1724 }
1725 extended_rna_path[rna_path_len + 1 + item_index_buff_len] = ']';
1726 extended_rna_path[extended_rna_path_len] = '\0';
1727 }
1728 else {
1729 extended_rna_path = (char *)rna_path;
1730 extended_rna_path_len = rna_path_len;
1731 }
1732 }
1733
1734 const bool match = RNA_struct_override_matches(bmain,
1735 propptr_a,
1736 propptr_b,
1737 extended_rna_path,
1738 extended_rna_path_len,
1739 liboverride,
1740 liboverride_flags,
1741 &ptrdiff_ctx.rnadiff_ctx.report_flag);
1742 ptrdiff_ctx.rnadiff_ctx.comparison = !match;
1743
1744 /* Regardless of whether the data from both pointers matches or not, a potentially existing
1745 * operation on current extended rna path should be removed. This is done by tagging said
1746 * operation as unused, while clearing the property tag (see also
1747 * #RNA_struct_override_matches handling of #LIBOVERRIDE_PROP_OP_TAG_UNUSED). Note that a
1748 * property with no operations will also be cleared by
1749 * #BKE_lib_override_library_id_unused_cleanup. */
1751 extended_rna_path);
1752 if (op != nullptr) {
1754 }
1755
1756 if (!ELEM(extended_rna_path, extended_rna_path_buffer, rna_path)) {
1757 MEM_freeN(extended_rna_path);
1758 }
1759
1760# undef RNA_PATH_BUFFSIZE
1761 }
1762 }
1763 else {
1764 /* We could also use is_diff_pointer, but then we potentially lose the greater-than/less-than
1765 * info - and don't think performances are critical here for now anyway. */
1766 ptrdiff_ctx.rnadiff_ctx.comparison = !RNA_struct_equals(bmain, propptr_a, propptr_b, mode);
1767 }
1768}
1769
1770# define RNA_PROPERTY_GET_SINGLE(_typename, _ptr, _prop, _index) \
1771 (is_array ? RNA_property_##_typename##_get_index((_ptr), (_prop), (_index)) : \
1772 RNA_property_##_typename##_get((_ptr), (_prop)))
1773# define RNA_PROPERTY_SET_SINGLE(_typename, _ptr, _prop, _index, _value) \
1774 (is_array ? RNA_property_##_typename##_set_index((_ptr), (_prop), (_index), (_value)) : \
1775 RNA_property_##_typename##_set((_ptr), (_prop), (_value)))
1776
1783{
1784 PropertyRNAOrID *prop_a = rnadiff_ctx.prop_a;
1785 PropertyRNAOrID *prop_b = rnadiff_ctx.prop_b;
1786 PointerRNA *ptr_a = prop_a->ptr;
1787 PointerRNA *ptr_b = prop_b->ptr;
1788 PropertyRNA *rawprop_a = prop_a->rawprop;
1789 PropertyRNA *rawprop_b = prop_b->rawprop;
1790 const uint len_a = prop_a->array_len;
1791 const uint len_b = prop_b->array_len;
1792
1793 IDOverrideLibrary *liboverride = rnadiff_ctx.liboverride;
1794 const char *rna_path = rnadiff_ctx.rna_path;
1795 const int liboverride_flags = rnadiff_ctx.liboverride_flags;
1796
1797 BLI_assert(len_a == len_b);
1798
1799 /* NOTE: at this point, we are sure that when len_a is zero,
1800 * we are not handling an (empty) array. */
1801
1802 const bool do_create = liboverride != nullptr &&
1803 (liboverride_flags & RNA_OVERRIDE_COMPARE_CREATE) != 0 &&
1804 rna_path != nullptr;
1805
1806 const bool no_ownership = (prop_a->rnaprop->flag & PROP_PTR_NO_OWNERSHIP) != 0;
1807
1808 const PropertyType rna_prop_type = RNA_property_type(prop_a->rnaprop);
1809 bool created = false;
1810 IDOverrideLibraryProperty *op = nullptr;
1811
1812 switch (rna_prop_type) {
1813 case PROP_BOOLEAN: {
1814 if (len_a) {
1815 bool array_stack_a[RNA_STACK_ARRAY], array_stack_b[RNA_STACK_ARRAY];
1816 bool *array_a, *array_b;
1817
1818 array_a = (len_a > RNA_STACK_ARRAY) ?
1819 MEM_malloc_arrayN<bool>(size_t(len_a), "RNA equals") :
1820 array_stack_a;
1821 array_b = (len_b > RNA_STACK_ARRAY) ?
1822 MEM_malloc_arrayN<bool>(size_t(len_b), "RNA equals") :
1823 array_stack_b;
1824
1825 RNA_property_boolean_get_array(ptr_a, rawprop_a, array_a);
1826 RNA_property_boolean_get_array(ptr_b, rawprop_b, array_b);
1827
1828 rnadiff_ctx.comparison = memcmp(array_a, array_b, sizeof(bool) * len_a);
1829
1830 if (do_create && rnadiff_ctx.comparison != 0) {
1831 /* XXX TODO: this will have to be refined to handle array items. */
1832 op = BKE_lib_override_library_property_get(liboverride, rna_path, &created);
1833
1834 if (op != nullptr && created) {
1837 nullptr,
1838 nullptr,
1839 {},
1840 {},
1841 -1,
1842 -1,
1843 true,
1844 nullptr,
1845 nullptr);
1847 }
1848 else {
1849 /* Already overridden prop, we'll have to check arrays items etc. */
1850 }
1851 }
1852
1853 if (array_a != array_stack_a) {
1854 MEM_freeN(array_a);
1855 }
1856 if (array_b != array_stack_b) {
1857 MEM_freeN(array_b);
1858 }
1859 }
1860 else {
1861 const bool value_a = RNA_property_boolean_get(ptr_a, rawprop_a);
1862 const bool value_b = RNA_property_boolean_get(ptr_b, rawprop_b);
1863 rnadiff_ctx.comparison = (value_a < value_b) ? -1 : (value_a > value_b) ? 1 : 0;
1864
1865 if (do_create && rnadiff_ctx.comparison != 0) {
1866 op = BKE_lib_override_library_property_get(liboverride, rna_path, &created);
1867
1868 if (op != nullptr && created) { /* If not yet overridden... */
1869 BKE_lib_override_library_property_operation_get(op,
1870 LIBOVERRIDE_OP_REPLACE,
1871 nullptr,
1872 nullptr,
1873 {},
1874 {},
1875 -1,
1876 -1,
1877 true,
1878 nullptr,
1879 nullptr);
1880 rnadiff_ctx.report_flag |= RNA_OVERRIDE_MATCH_RESULT_CREATED;
1881 }
1882 }
1883 }
1884 break;
1885 }
1886
1887 case PROP_INT: {
1888 if (len_a) {
1889 int array_stack_a[RNA_STACK_ARRAY], array_stack_b[RNA_STACK_ARRAY];
1890 int *array_a, *array_b;
1891
1892 array_a = (len_a > RNA_STACK_ARRAY) ? MEM_malloc_arrayN<int>(size_t(len_a), "RNA equals") :
1893 array_stack_a;
1894 array_b = (len_b > RNA_STACK_ARRAY) ? MEM_malloc_arrayN<int>(size_t(len_b), "RNA equals") :
1895 array_stack_b;
1896
1897 RNA_property_int_get_array(ptr_a, rawprop_a, array_a);
1898 RNA_property_int_get_array(ptr_b, rawprop_b, array_b);
1899
1900 rnadiff_ctx.comparison = memcmp(array_a, array_b, sizeof(int) * len_a);
1901
1902 if (do_create && rnadiff_ctx.comparison != 0) {
1903 /* XXX TODO: this will have to be refined to handle array items. */
1904 op = BKE_lib_override_library_property_get(liboverride, rna_path, &created);
1905
1906 if (op != nullptr && created) {
1909 nullptr,
1910 nullptr,
1911 {},
1912 {},
1913 -1,
1914 -1,
1915 true,
1916 nullptr,
1917 nullptr);
1918 if (created) {
1920 }
1921 }
1922 else {
1923 /* Already overridden prop, we'll have to check arrays items etc. */
1924 }
1925 }
1926
1927 if (array_a != array_stack_a) {
1928 MEM_freeN(array_a);
1929 }
1930 if (array_b != array_stack_b) {
1931 MEM_freeN(array_b);
1932 }
1933 }
1934 else {
1935 const int value_a = RNA_property_int_get(ptr_a, rawprop_a);
1936 const int value_b = RNA_property_int_get(ptr_b, rawprop_b);
1937 rnadiff_ctx.comparison = (value_a < value_b) ? -1 : (value_a > value_b) ? 1 : 0;
1938
1939 if (do_create && rnadiff_ctx.comparison != 0) {
1940 op = BKE_lib_override_library_property_get(liboverride, rna_path, &created);
1941
1942 if (op != nullptr && created) { /* If not yet overridden... */
1943 BKE_lib_override_library_property_operation_get(op,
1944 LIBOVERRIDE_OP_REPLACE,
1945 nullptr,
1946 nullptr,
1947 {},
1948 {},
1949 -1,
1950 -1,
1951 true,
1952 nullptr,
1953 nullptr);
1954 rnadiff_ctx.report_flag |= RNA_OVERRIDE_MATCH_RESULT_CREATED;
1955 }
1956 }
1957 }
1958 break;
1959 }
1960
1961 case PROP_FLOAT: {
1962 if (len_a) {
1963 float array_stack_a[RNA_STACK_ARRAY], array_stack_b[RNA_STACK_ARRAY];
1964 float *array_a, *array_b;
1965
1966 array_a = (len_a > RNA_STACK_ARRAY) ?
1967 MEM_malloc_arrayN<float>(size_t(len_a), "RNA equals") :
1968 array_stack_a;
1969 array_b = (len_b > RNA_STACK_ARRAY) ?
1970 MEM_malloc_arrayN<float>(size_t(len_b), "RNA equals") :
1971 array_stack_b;
1972
1973 RNA_property_float_get_array(ptr_a, rawprop_a, array_a);
1974 RNA_property_float_get_array(ptr_b, rawprop_b, array_b);
1975
1976 rnadiff_ctx.comparison = memcmp(array_a, array_b, sizeof(float) * len_a);
1977
1978 if (do_create && rnadiff_ctx.comparison != 0) {
1979 /* XXX TODO: this will have to be refined to handle array items. */
1980 op = BKE_lib_override_library_property_get(liboverride, rna_path, &created);
1981
1982 if (op != nullptr && created) {
1985 nullptr,
1986 nullptr,
1987 {},
1988 {},
1989 -1,
1990 -1,
1991 true,
1992 nullptr,
1993 nullptr);
1995 }
1996 else {
1997 /* Already overridden prop, we'll have to check arrays items etc. */
1998 }
1999 }
2000
2001 if (array_a != array_stack_a) {
2002 MEM_freeN(array_a);
2003 }
2004 if (array_b != array_stack_b) {
2005 MEM_freeN(array_b);
2006 }
2007 }
2008 else {
2009 const float value_a = RNA_property_float_get(ptr_a, rawprop_a);
2010 const float value_b = RNA_property_float_get(ptr_b, rawprop_b);
2011 rnadiff_ctx.comparison = (value_a < value_b) ? -1 : (value_a > value_b) ? 1 : 0;
2012
2013 if (do_create && rnadiff_ctx.comparison != 0) {
2014 op = BKE_lib_override_library_property_get(liboverride, rna_path, &created);
2015
2016 if (op != nullptr && created) { /* If not yet overridden... */
2017 BKE_lib_override_library_property_operation_get(op,
2018 LIBOVERRIDE_OP_REPLACE,
2019 nullptr,
2020 nullptr,
2021 {},
2022 {},
2023 -1,
2024 -1,
2025 true,
2026 nullptr,
2027 nullptr);
2028 rnadiff_ctx.report_flag |= RNA_OVERRIDE_MATCH_RESULT_CREATED;
2029 }
2030 }
2031 }
2032 break;
2033 }
2034
2035 case PROP_ENUM: {
2036 const int value_a = RNA_property_enum_get(ptr_a, rawprop_a);
2037 const int value_b = RNA_property_enum_get(ptr_b, rawprop_b);
2038 rnadiff_ctx.comparison = value_a != value_b;
2039
2040 if (do_create && rnadiff_ctx.comparison != 0) {
2041 op = BKE_lib_override_library_property_get(liboverride, rna_path, &created);
2042
2043 if (op != nullptr && created) { /* If not yet overridden... */
2046 nullptr,
2047 nullptr,
2048 {},
2049 {},
2050 -1,
2051 -1,
2052 true,
2053 nullptr,
2054 nullptr);
2056 }
2057 }
2058 break;
2059 }
2060
2061 case PROP_STRING: {
2062 char fixed_a[4096], fixed_b[4096];
2063 int len_str_a, len_str_b;
2064 char *value_a = RNA_property_string_get_alloc(
2065 ptr_a, rawprop_a, fixed_a, sizeof(fixed_a), &len_str_a);
2066 char *value_b = RNA_property_string_get_alloc(
2067 ptr_b, rawprop_b, fixed_b, sizeof(fixed_b), &len_str_b);
2068/* TODO: we could do a check on length too,
2069 * but then we would not have a 'real' string comparison...
2070 * Maybe behind a eRNAOverrideMatch flag? */
2071# if 0
2072 rnadiff_ctx.comparison = len_str_a < len_str_b ? -1 :
2073 len_str_a > len_str_b ? 1 :
2074 strcmp(value_a, value_b);
2075# endif
2076 rnadiff_ctx.comparison = strcmp(value_a, value_b);
2077
2078 if (do_create && rnadiff_ctx.comparison != 0) {
2079 op = BKE_lib_override_library_property_get(liboverride, rna_path, &created);
2080
2081 if (op != nullptr && created) { /* If not yet overridden... */
2084 nullptr,
2085 nullptr,
2086 {},
2087 {},
2088 -1,
2089 -1,
2090 true,
2091 nullptr,
2092 nullptr);
2094 }
2095 }
2096
2097 if (value_a != fixed_a) {
2098 MEM_freeN(value_a);
2099 }
2100 if (value_b != fixed_b) {
2101 MEM_freeN(value_b);
2102 }
2103 break;
2104 }
2105
2106 case PROP_POINTER: {
2107 /* Using property name check only makes sense for items of a collection, not for a single
2108 * pointer.
2109 * Doing this here avoids having to manually specify `PROPOVERRIDE_NO_PROP_NAME` to things
2110 * like ShapeKey pointers. */
2111 if (STREQ(prop_a->identifier, "rna_type")) {
2112 /* Dummy 'pass' answer, this is a meta-data and must be ignored... */
2113 return;
2114 }
2115 else {
2116 RNACompareOverrideDiffPropPtrContext ptrdiff_ctx(rnadiff_ctx);
2117 ptrdiff_ctx.owner_id_a = ptr_a->owner_id;
2118 ptrdiff_ctx.owner_id_b = ptr_b->owner_id;
2119 ptrdiff_ctx.propptr_a = RNA_property_pointer_get(ptr_a, rawprop_a);
2120 ptrdiff_ctx.propptr_b = RNA_property_pointer_get(ptr_b, rawprop_b);
2121 ptrdiff_ctx.no_prop_name = true;
2122 ptrdiff_ctx.no_ownership = no_ownership;
2123 ptrdiff_ctx.property_type = PROP_POINTER;
2124 /* IDProperties (real or backend storage for dynamic RNA) have a default handling for
2125 * 'pointer' data creation. */
2126 if (prop_a->is_idprop || prop_a->is_rna_storage_idprop || prop_a->rnaprop->override_apply)
2127 {
2128 BLI_assert(prop_a->is_idprop == prop_b->is_idprop);
2131 ptrdiff_ctx.has_liboverride_apply_cb = true;
2132 }
2133 rna_property_override_diff_propptr(bmain, ptrdiff_ctx);
2134 }
2135 break;
2136 }
2137
2138 case PROP_COLLECTION: {
2139 const bool no_prop_name = (prop_a->rnaprop->flag_override & PROPOVERRIDE_NO_PROP_NAME) != 0;
2140
2141 /* IDProperties (real or backend storage for dynamic RNA) have a default handling for
2142 * 'pointer' data creation and 'collection' items insertion. */
2143 BLI_assert(prop_a->is_idprop == prop_b->is_idprop);
2146 const bool has_liboverride_apply_cb = (prop_a->is_idprop || prop_a->is_rna_storage_idprop ||
2147 prop_a->rnaprop->override_apply);
2148 if (!has_liboverride_apply_cb &&
2150 {
2151 CLOG_ERROR(&LOG_COMPARE_OVERRIDE,
2152 "RNA collection '%s' defined as supporting liboverride insertion of items, but "
2153 "no liboverride apply callback defined for it. No insertion will happen.",
2154 rna_path);
2155 }
2156
2157 /* NOTE: we assume we only insert in ptr_a (i.e. we can only get new items in ptr_a),
2158 * and that we never remove anything. */
2159 const bool use_collection_insertion = has_liboverride_apply_cb && do_create &&
2160 (prop_a->rnaprop->flag_override &
2162
2163 bool equals = true;
2164 bool abort = false;
2165 int idx_a = 0;
2166 int idx_b = 0;
2167 std::optional<std::string> prev_rna_itemname_a;
2168 std::optional<ID *> prev_rna_itemid_a;
2169
2170 CollectionPropertyIterator iter_a, iter_b;
2171 RNA_property_collection_begin(ptr_a, rawprop_a, &iter_a);
2172 RNA_property_collection_begin(ptr_b, rawprop_b, &iter_b);
2173
2174 if (use_collection_insertion) {
2175 /* We need to clean up all possible existing insertion operations, and then re-generate
2176 * them, otherwise we'd end up with a mess of opop's every time something changes. */
2177 op = BKE_lib_override_library_property_find(liboverride, rna_path);
2178 if (op != nullptr) {
2182 }
2183 }
2184 op = nullptr;
2185 }
2186 }
2187
2188 for (; iter_a.valid && !abort;) {
2189 do {
2190 bool is_valid_for_insertion = use_collection_insertion;
2191
2192 RNACompareOverrideDiffPropPtrContext ptrdiff_ctx(rnadiff_ctx);
2193 ptrdiff_ctx.owner_id_a = ptr_a->owner_id;
2194 ptrdiff_ctx.owner_id_b = ptr_b->owner_id;
2195 ptrdiff_ctx.propptr_a = iter_a.ptr;
2196 if (iter_b.valid) {
2197 ptrdiff_ctx.propptr_b = iter_b.ptr;
2198 }
2199 ptrdiff_ctx.no_prop_name = no_prop_name;
2200 ptrdiff_ctx.do_force_name = !no_prop_name;
2201 ptrdiff_ctx.use_id_pointer = !no_prop_name;
2202 ptrdiff_ctx.no_ownership = no_ownership;
2203 ptrdiff_ctx.property_type = PROP_COLLECTION;
2204 ptrdiff_ctx.has_liboverride_apply_cb = has_liboverride_apply_cb;
2205
2206 if (iter_b.valid || use_collection_insertion) {
2207 rna_property_override_diff_propptr_validate_diffing(ptrdiff_ctx);
2208 /* Getting props names has already been done in call above, no need to redo it later
2209 * when calling #rna_property_override_diff_propptr. */
2210 ptrdiff_ctx.no_prop_name = true;
2211 ptrdiff_ctx.do_force_name = false;
2212 ptrdiff_ctx.use_id_pointer = false;
2213 }
2214
2215 const bool is_valid_for_diffing = ptrdiff_ctx.is_valid_for_diffing;
2216 const bool is_id = ptrdiff_ctx.is_id;
2217
2218 /* We do not support insertion of IDs for now, neither handle nullptr pointers. */
2219 if (is_id || is_valid_for_diffing) {
2220 is_valid_for_insertion = false;
2221 }
2222
2223# if 0
2224 if (rna_path) {
2225 printf(
2226 "Checking %s, %s [%d] vs %s [%d]; is_id: %d, diffing: %d; "
2227 "insert: %d (could be used: %d, do_create: %d)\n",
2228 rna_path,
2229 ptrdiff_ctx.rna_itemname_a ? ptrdiff_ctx.rna_itemname_a->c_str() : "",
2230 idx_a,
2231 ptrdiff_ctx.rna_itemname_b ? ptrdiff_ctx.rna_itemname_b->c_str() : "",
2232 idx_b,
2233 is_id,
2234 is_valid_for_diffing,
2235 is_valid_for_insertion,
2236 use_collection_insertion,
2237 do_create);
2238 }
2239# endif
2240
2241 if (!(is_id || is_valid_for_diffing || is_valid_for_insertion)) {
2242 /* Differences we cannot handle, we can break here. */
2243 equals = false;
2244 abort = true;
2245 break;
2246 }
2247
2248 /* Collections do not support replacement of their data (except for collections of ID
2249 * pointers), since they do not support removing, only in *some* cases, insertion. We
2250 * also assume then that _a data is the one where things are inserted.
2251 *
2252 * NOTE: In insertion case, both 'local' and 'reference' (aka anchor) sub-item
2253 * identifiers refer to collection items in the local override. The 'reference' may match
2254 * an item in the linked reference data, but it can also be another local-only item added
2255 * by a previous INSERT operation. */
2256 if (is_valid_for_insertion && use_collection_insertion) {
2257 op = BKE_lib_override_library_property_get(liboverride, rna_path, &created);
2258
2260 op,
2262 (no_prop_name || !prev_rna_itemname_a) ? nullptr : prev_rna_itemname_a->c_str(),
2263 (no_prop_name || !ptrdiff_ctx.rna_itemname_a) ?
2264 nullptr :
2265 ptrdiff_ctx.rna_itemname_a->c_str(),
2266 prev_rna_itemid_a,
2267 ptrdiff_ctx.rna_itemid_a,
2268 idx_a - 1,
2269 idx_a,
2270 true,
2271 nullptr,
2272 nullptr);
2273# if 0
2274 printf("%s: Adding insertion op override after '%s'/%d\n",
2275 rna_path,
2276 prev_rna_itemname_a ? prev_rna_itemname_a->c_str() : "",
2277 idx_a - 1);
2278# endif
2279 op = nullptr;
2280
2281 equals = false;
2282 }
2283 else if (is_id || is_valid_for_diffing) {
2284 if (equals || do_create) {
2285 ptrdiff_ctx.rna_itemindex_a = idx_a;
2286 ptrdiff_ctx.rna_itemindex_b = idx_b;
2287 rna_property_override_diff_propptr(bmain, ptrdiff_ctx);
2288 equals = equals && (rnadiff_ctx.comparison == 0);
2289 }
2290 }
2291
2292 if (ptrdiff_ctx.rna_itemname_a) {
2293 prev_rna_itemname_a = std::move(*ptrdiff_ctx.rna_itemname_a);
2294 }
2295 else {
2296 prev_rna_itemname_a.reset();
2297 }
2298 prev_rna_itemid_a = ptrdiff_ctx.rna_itemid_a;
2299
2300 if (!do_create && !equals) {
2301 abort = true; /* Early out in case we do not want to loop over whole collection. */
2302 break;
2303 }
2304
2305 if (!(use_collection_insertion && !(is_id || is_valid_for_diffing))) {
2306 break;
2307 }
2308
2309 if (iter_a.valid) {
2311 idx_a++;
2312 }
2313 } while (iter_a.valid);
2314
2315 if (iter_a.valid) {
2317 idx_a++;
2318 }
2319 if (iter_b.valid) {
2321 idx_b++;
2322 }
2323 }
2324
2325 /* Not same number of items in both collections. */
2326 equals = equals && !(iter_a.valid || iter_b.valid) && !abort;
2329
2330 rnadiff_ctx.comparison = (equals == false);
2331 return;
2332 }
2333
2334 default:
2335 break;
2336 }
2337
2338 if (op != nullptr) {
2339 /* In theory, if the liboverride operation already existed, it should already be of the right
2340 * type. However, in some rare cases a same exact RNA path can end up pointing at different
2341 * data of a different path than when the liboverride property was created, so just always
2342 * ensure the type is now valid. */
2343 op->rna_prop_type = rna_prop_type;
2344 }
2345
2346 return;
2347}
2348
2350 PointerRNA *ptr_local,
2351 PointerRNA *ptr_reference,
2352 PointerRNA *ptr_storage,
2353 PropertyRNA *prop_local,
2354 PropertyRNA *prop_reference,
2355 PropertyRNA *prop_storage,
2356 const int len_local,
2357 const int len_reference,
2358 const int len_storage,
2360{
2361 BLI_assert(len_local == len_reference && (!ptr_storage || len_local == len_storage));
2362 UNUSED_VARS_NDEBUG(len_reference, len_storage);
2363
2364 bool changed = false;
2365 const bool is_array = len_local > 0;
2366 const int index = is_array ? opop->subitem_reference_index : 0;
2367
2369 {
2370 return changed;
2371 }
2372
2373 /* XXX TODO: About range limits.
2374 * Ideally, it would be great to get rid of RNA range in that specific case.
2375 * However, this won't be that easy and will add yet another layer of complexity in
2376 * generated code, not to mention that we could most likely *not* bypass custom setters anyway.
2377 * So for now, if needed second operand value is not in valid range, we simply fall back
2378 * to a mere REPLACE operation.
2379 * Time will say whether this is acceptable limitation or not. */
2380 switch (RNA_property_type(prop_local)) {
2381 case PROP_BOOLEAN:
2382 /* TODO: support boolean ops? Really doubt this would ever be useful though. */
2383 BLI_assert_msg(0, "Boolean properties support no override diff operation");
2384 break;
2385 case PROP_INT: {
2386 int prop_min, prop_max;
2387 RNA_property_int_range(ptr_local, prop_local, &prop_min, &prop_max);
2388
2389 if (is_array && index == -1) {
2390 int array_stack_a[RNA_STACK_ARRAY], array_stack_b[RNA_STACK_ARRAY];
2391 int *array_a, *array_b;
2392
2393 array_a = (len_local > RNA_STACK_ARRAY) ?
2394 MEM_malloc_arrayN<int>(size_t(len_local), __func__) :
2395 array_stack_a;
2396 RNA_property_int_get_array(ptr_reference, prop_reference, array_a);
2397
2398 switch (opop->operation) {
2399 case LIBOVERRIDE_OP_ADD:
2401 const int fac = opop->operation == LIBOVERRIDE_OP_ADD ? 1 : -1;
2402 const int other_op = opop->operation == LIBOVERRIDE_OP_ADD ? LIBOVERRIDE_OP_SUBTRACT :
2404 bool do_set = true;
2405 array_b = (len_local > RNA_STACK_ARRAY) ?
2406 MEM_malloc_arrayN<int>(size_t(len_local), __func__) :
2407 array_stack_b;
2408 RNA_property_int_get_array(ptr_local, prop_local, array_b);
2409 for (int i = len_local; i--;) {
2410 array_b[i] = fac * (array_b[i] - array_a[i]);
2411 if (array_b[i] < prop_min || array_b[i] > prop_max) {
2412 opop->operation = other_op;
2413 for (int j = len_local; j--;) {
2414 array_b[j] = j >= i ? -array_b[j] : fac * (array_a[j] - array_b[j]);
2415 if (array_b[j] < prop_min || array_b[j] > prop_max) {
2416 /* We failed to find a suitable diff op,
2417 * fall back to plain REPLACE one. */
2419 do_set = false;
2420 break;
2421 }
2422 }
2423 break;
2424 }
2425 }
2426 if (do_set) {
2427 changed = true;
2428 RNA_property_int_set_array(ptr_storage, prop_storage, array_b);
2429 }
2430 if (array_b != array_stack_b) {
2431 MEM_freeN(array_b);
2432 }
2433 break;
2434 }
2435 default:
2436 BLI_assert_msg(0, "Unsupported RNA override diff operation on integer");
2437 break;
2438 }
2439
2440 if (array_a != array_stack_a) {
2441 MEM_freeN(array_a);
2442 }
2443 }
2444 else {
2445 const int value = RNA_PROPERTY_GET_SINGLE(int, ptr_reference, prop_reference, index);
2446
2447 switch (opop->operation) {
2448 case LIBOVERRIDE_OP_ADD:
2450 const int fac = opop->operation == LIBOVERRIDE_OP_ADD ? 1 : -1;
2451 const int other_op = opop->operation == LIBOVERRIDE_OP_ADD ? LIBOVERRIDE_OP_SUBTRACT :
2453 int b = fac * (RNA_PROPERTY_GET_SINGLE(int, ptr_local, prop_local, index) - value);
2454 if (b < prop_min || b > prop_max) {
2455 opop->operation = other_op;
2456 b = -b;
2457 if (b < prop_min || b > prop_max) {
2459 break;
2460 }
2461 }
2462 changed = true;
2463 RNA_PROPERTY_SET_SINGLE(int, ptr_storage, prop_storage, index, b);
2464 break;
2465 }
2466 default:
2467 BLI_assert_msg(0, "Unsupported RNA override diff operation on integer");
2468 break;
2469 }
2470 }
2471 break;
2472 }
2473 case PROP_FLOAT: {
2474 float prop_min, prop_max;
2475 RNA_property_float_range(ptr_local, prop_local, &prop_min, &prop_max);
2476
2477 if (is_array && index == -1) {
2478 float array_stack_a[RNA_STACK_ARRAY], array_stack_b[RNA_STACK_ARRAY];
2479 float *array_a, *array_b;
2480
2481 array_a = (len_local > RNA_STACK_ARRAY) ?
2482 MEM_malloc_arrayN<float>(size_t(len_local), __func__) :
2483 array_stack_a;
2484
2485 RNA_property_float_get_array(ptr_reference, prop_reference, array_a);
2486 switch (opop->operation) {
2487 case LIBOVERRIDE_OP_ADD:
2489 const float fac = opop->operation == LIBOVERRIDE_OP_ADD ? 1.0 : -1.0;
2490 const int other_op = opop->operation == LIBOVERRIDE_OP_ADD ? LIBOVERRIDE_OP_SUBTRACT :
2492 bool do_set = true;
2493 array_b = (len_local > RNA_STACK_ARRAY) ?
2494 MEM_malloc_arrayN<float>(size_t(len_local), __func__) :
2495 array_stack_b;
2496 RNA_property_float_get_array(ptr_local, prop_local, array_b);
2497 for (int i = len_local; i--;) {
2498 array_b[i] = fac * (array_b[i] - array_a[i]);
2499 if (array_b[i] < prop_min || array_b[i] > prop_max) {
2500 opop->operation = other_op;
2501 for (int j = len_local; j--;) {
2502 array_b[j] = j >= i ? -array_b[j] : fac * (array_a[j] - array_b[j]);
2503 if (array_b[j] < prop_min || array_b[j] > prop_max) {
2504 /* We failed to find a suitable diff op,
2505 * fall back to plain REPLACE one. */
2507 do_set = false;
2508 break;
2509 }
2510 }
2511 break;
2512 }
2513 }
2514 if (do_set) {
2515 changed = true;
2516 RNA_property_float_set_array(ptr_storage, prop_storage, array_b);
2517 }
2518 if (array_b != array_stack_b) {
2519 MEM_freeN(array_b);
2520 }
2521 break;
2522 }
2524 bool do_set = true;
2525 array_b = (len_local > RNA_STACK_ARRAY) ?
2526 MEM_malloc_arrayN<float>(size_t(len_local), __func__) :
2527 array_stack_b;
2528 RNA_property_float_get_array(ptr_local, prop_local, array_b);
2529 for (int i = len_local; i--;) {
2530 array_b[i] = array_a[i] == 0.0f ? array_b[i] : array_b[i] / array_a[i];
2531 if (array_b[i] < prop_min || array_b[i] > prop_max) {
2533 do_set = false;
2534 break;
2535 }
2536 }
2537 if (do_set) {
2538 changed = true;
2539 RNA_property_float_set_array(ptr_storage, prop_storage, array_b);
2540 }
2541 if (array_b != array_stack_b) {
2542 MEM_freeN(array_b);
2543 }
2544 break;
2545 }
2546 default:
2547 BLI_assert_msg(0, "Unsupported RNA override diff operation on float");
2548 break;
2549 }
2550
2551 if (array_a != array_stack_a) {
2552 MEM_freeN(array_a);
2553 }
2554 }
2555 else {
2556 const float value = RNA_PROPERTY_GET_SINGLE(float, ptr_reference, prop_reference, index);
2557
2558 switch (opop->operation) {
2559 case LIBOVERRIDE_OP_ADD:
2561 const float fac = opop->operation == LIBOVERRIDE_OP_ADD ? 1.0f : -1.0f;
2562 const int other_op = opop->operation == LIBOVERRIDE_OP_ADD ? LIBOVERRIDE_OP_SUBTRACT :
2564 float b = fac * (RNA_PROPERTY_GET_SINGLE(float, ptr_local, prop_local, index) - value);
2565 if (b < prop_min || b > prop_max) {
2566 opop->operation = other_op;
2567 b = -b;
2568 if (b < prop_min || b > prop_max) {
2570 break;
2571 }
2572 }
2573 changed = true;
2574 RNA_PROPERTY_SET_SINGLE(float, ptr_storage, prop_storage, index, b);
2575 break;
2576 }
2578 const float b = RNA_property_float_get_index(ptr_local, prop_local, index) /
2579 (value == 0.0f ? 1.0f : value);
2580 if (b < prop_min || b > prop_max) {
2582 break;
2583 }
2584 changed = true;
2585 RNA_property_float_set_index(ptr_storage, prop_storage, index, b);
2586 break;
2587 }
2588 default:
2589 BLI_assert_msg(0, "Unsupported RNA override diff operation on float");
2590 break;
2591 }
2592 }
2593 return true;
2594 }
2595 case PROP_ENUM:
2596 /* TODO: support add/sub, for bitflags? */
2597 BLI_assert_msg(0, "Enum properties support no override diff operation");
2598 break;
2599 case PROP_POINTER:
2600 BLI_assert_msg(0, "Pointer properties support no override diff operation");
2601 break;
2602 case PROP_STRING:
2603 BLI_assert_msg(0, "String properties support no override diff operation");
2604 break;
2605 case PROP_COLLECTION:
2606 /* XXX TODO: support this of course... */
2607 BLI_assert_msg(0, "Collection properties support no override diff operation");
2608 break;
2609 default:
2610 break;
2611 }
2612
2613 return changed;
2614}
2615
2617 RNAPropertyOverrideApplyContext &rnaapply_ctx)
2618{
2619 PointerRNA *ptr_dst = &rnaapply_ctx.ptr_dst;
2620 PointerRNA *ptr_src = &rnaapply_ctx.ptr_src;
2621 PointerRNA *ptr_storage = &rnaapply_ctx.ptr_storage;
2622 PropertyRNA *prop_dst = rnaapply_ctx.prop_dst;
2623 PropertyRNA *prop_src = rnaapply_ctx.prop_src;
2624 PropertyRNA *prop_storage = rnaapply_ctx.prop_storage;
2625 const int len_dst = rnaapply_ctx.len_src;
2626 const int len_src = rnaapply_ctx.len_src;
2627 const int len_storage = rnaapply_ctx.len_storage;
2629
2630 const PropertyType prop_src_type = RNA_property_type(prop_src);
2631 const PropertyType prop_dst_type = RNA_property_type(prop_dst);
2632
2633 /* It is possible that a same exact RNA path points to a different property of a different type
2634 * (due to changes in the program, or in some custom data...). */
2635 if (prop_src_type != prop_dst_type ||
2636 (prop_storage && prop_src_type != RNA_property_type(prop_storage)))
2637 {
2638 std::optional<std::string> prop_rna_path = rnaapply_ctx.liboverride_property ?
2639 rnaapply_ctx.liboverride_property->rna_path :
2640 RNA_path_from_ID_to_property(ptr_dst, prop_dst);
2641 CLOG_WARN(&LOG_COMPARE_OVERRIDE,
2642 "%s.%s: Inconsistency between stored property type (%d) and linked reference one "
2643 "(%d), skipping liboverride apply",
2644 ptr_dst->owner_id->name,
2645 prop_rna_path ? prop_rna_path->c_str() :
2646 fmt::format(" ... .{}", prop_dst->name).c_str(),
2647 prop_src_type,
2648 prop_dst_type);
2649 /* Keep the liboverride property, update its type to the new actual one. */
2650 if (rnaapply_ctx.liboverride_property) {
2651 rnaapply_ctx.liboverride_property->rna_prop_type = prop_dst_type;
2652 }
2653 return false;
2654 }
2655
2656 BLI_assert(len_dst == len_src && (!prop_storage || len_dst == len_storage));
2657 UNUSED_VARS_NDEBUG(len_src, len_storage);
2658
2659 const bool is_array = len_dst > 0;
2660 const int index = is_array ? opop->subitem_reference_index : 0;
2661 const short override_op = opop->operation;
2662
2663 bool ret_success = true;
2664
2665 switch (RNA_property_type(prop_dst)) {
2666 case PROP_BOOLEAN:
2667 if (is_array && index == -1) {
2668 bool array_stack_a[RNA_STACK_ARRAY];
2669 bool *array_a;
2670
2671 array_a = (len_dst > RNA_STACK_ARRAY) ?
2672 MEM_malloc_arrayN<bool>(size_t(len_dst), __func__) :
2673 array_stack_a;
2674
2675 RNA_property_boolean_get_array(ptr_src, prop_src, array_a);
2676
2677 switch (override_op) {
2679 RNA_property_boolean_set_array(ptr_dst, prop_dst, array_a);
2680 break;
2681 default:
2682 BLI_assert_msg(0, "Unsupported RNA override operation on boolean");
2683 return false;
2684 }
2685
2686 if (array_a != array_stack_a) {
2687 MEM_freeN(array_a);
2688 }
2689 }
2690 else {
2691 const bool value = RNA_PROPERTY_GET_SINGLE(boolean, ptr_src, prop_src, index);
2692
2693 switch (override_op) {
2695 RNA_PROPERTY_SET_SINGLE(boolean, ptr_dst, prop_dst, index, value);
2696 break;
2697 default:
2698 BLI_assert_msg(0, "Unsupported RNA override operation on boolean");
2699 return false;
2700 }
2701 }
2702 break;
2703 case PROP_INT:
2704 if (is_array && index == -1) {
2705 int array_stack_a[RNA_STACK_ARRAY], array_stack_b[RNA_STACK_ARRAY];
2706 int *array_a, *array_b;
2707
2708 array_a = (len_dst > RNA_STACK_ARRAY) ? MEM_malloc_arrayN<int>(size_t(len_dst), __func__) :
2709 array_stack_a;
2710
2711 switch (override_op) {
2713 RNA_property_int_get_array(ptr_src, prop_src, array_a);
2714 RNA_property_int_set_array(ptr_dst, prop_dst, array_a);
2715 break;
2716 case LIBOVERRIDE_OP_ADD:
2718 RNA_property_int_get_array(ptr_dst, prop_dst, array_a);
2719 array_b = (len_dst > RNA_STACK_ARRAY) ?
2720 MEM_malloc_arrayN<int>(size_t(len_dst), __func__) :
2721 array_stack_b;
2722 RNA_property_int_get_array(ptr_storage, prop_storage, array_b);
2723 if (override_op == LIBOVERRIDE_OP_ADD) {
2724 for (int i = len_dst; i--;) {
2725 array_a[i] += array_b[i];
2726 }
2727 }
2728 else {
2729 for (int i = len_dst; i--;) {
2730 array_a[i] -= array_b[i];
2731 }
2732 }
2733 RNA_property_int_set_array(ptr_dst, prop_dst, array_a);
2734 if (array_b != array_stack_b) {
2735 MEM_freeN(array_b);
2736 }
2737 break;
2738 default:
2739 BLI_assert_msg(0, "Unsupported RNA override operation on integer");
2740 return false;
2741 }
2742
2743 if (array_a != array_stack_a) {
2744 MEM_freeN(array_a);
2745 }
2746 }
2747 else {
2748 const int storage_value = prop_storage ? RNA_PROPERTY_GET_SINGLE(
2749 int, ptr_storage, prop_storage, index) :
2750 0;
2751
2752 switch (override_op) {
2754 RNA_PROPERTY_SET_SINGLE(int,
2755 ptr_dst,
2756 prop_dst,
2757 index,
2758 RNA_PROPERTY_GET_SINGLE(int, ptr_src, prop_src, index));
2759 break;
2760 case LIBOVERRIDE_OP_ADD:
2761 RNA_PROPERTY_SET_SINGLE(int,
2762 ptr_dst,
2763 prop_dst,
2764 index,
2765 RNA_PROPERTY_GET_SINGLE(int, ptr_dst, prop_dst, index) -
2766 storage_value);
2767 break;
2769 RNA_PROPERTY_SET_SINGLE(int,
2770 ptr_dst,
2771 prop_dst,
2772 index,
2773 RNA_PROPERTY_GET_SINGLE(int, ptr_dst, prop_dst, index) -
2774 storage_value);
2775 break;
2776 default:
2777 BLI_assert_msg(0, "Unsupported RNA override operation on integer");
2778 return false;
2779 }
2780 }
2781 break;
2782 case PROP_FLOAT:
2783 if (is_array && index == -1) {
2784 float array_stack_a[RNA_STACK_ARRAY], array_stack_b[RNA_STACK_ARRAY];
2785 float *array_a, *array_b;
2786
2787 array_a = (len_dst > RNA_STACK_ARRAY) ?
2788 MEM_malloc_arrayN<float>(size_t(len_dst), __func__) :
2789 array_stack_a;
2790
2791 switch (override_op) {
2793 RNA_property_float_get_array(ptr_src, prop_src, array_a);
2794 RNA_property_float_set_array(ptr_dst, prop_dst, array_a);
2795 break;
2796 case LIBOVERRIDE_OP_ADD:
2799 RNA_property_float_get_array(ptr_dst, prop_dst, array_a);
2800 array_b = (len_dst > RNA_STACK_ARRAY) ?
2801 MEM_malloc_arrayN<float>(size_t(len_dst), __func__) :
2802 array_stack_b;
2803 RNA_property_float_get_array(ptr_storage, prop_storage, array_b);
2804 if (override_op == LIBOVERRIDE_OP_ADD) {
2805 for (int i = len_dst; i--;) {
2806 array_a[i] += array_b[i];
2807 }
2808 }
2809 else if (override_op == LIBOVERRIDE_OP_SUBTRACT) {
2810 for (int i = len_dst; i--;) {
2811 array_a[i] -= array_b[i];
2812 }
2813 }
2814 else {
2815 for (int i = len_dst; i--;) {
2816 array_a[i] *= array_b[i];
2817 }
2818 }
2819 RNA_property_float_set_array(ptr_dst, prop_dst, array_a);
2820 if (array_b != array_stack_b) {
2821 MEM_freeN(array_b);
2822 }
2823 break;
2824 default:
2825 BLI_assert_msg(0, "Unsupported RNA override operation on float");
2826 return false;
2827 }
2828
2829 if (array_a != array_stack_a) {
2830 MEM_freeN(array_a);
2831 }
2832 }
2833 else {
2834 const float storage_value = prop_storage ? RNA_PROPERTY_GET_SINGLE(
2835 float, ptr_storage, prop_storage, index) :
2836 0.0f;
2837
2838 switch (override_op) {
2840 RNA_PROPERTY_SET_SINGLE(float,
2841 ptr_dst,
2842 prop_dst,
2843 index,
2844 RNA_PROPERTY_GET_SINGLE(float, ptr_src, prop_src, index));
2845 break;
2846 case LIBOVERRIDE_OP_ADD:
2847 RNA_PROPERTY_SET_SINGLE(float,
2848 ptr_dst,
2849 prop_dst,
2850 index,
2851 RNA_PROPERTY_GET_SINGLE(float, ptr_dst, prop_dst, index) +
2852 storage_value);
2853 break;
2855 RNA_PROPERTY_SET_SINGLE(float,
2856 ptr_dst,
2857 prop_dst,
2858 index,
2859 RNA_PROPERTY_GET_SINGLE(float, ptr_dst, prop_dst, index) -
2860 storage_value);
2861 break;
2863 RNA_PROPERTY_SET_SINGLE(float,
2864 ptr_dst,
2865 prop_dst,
2866 index,
2867 RNA_PROPERTY_GET_SINGLE(float, ptr_dst, prop_dst, index) *
2868 storage_value);
2869 break;
2870 default:
2871 BLI_assert_msg(0, "Unsupported RNA override operation on float");
2872 return false;
2873 }
2874 }
2875 break;
2876 case PROP_ENUM: {
2877 const int value = RNA_property_enum_get(ptr_src, prop_src);
2878
2879 switch (override_op) {
2881 RNA_property_enum_set(ptr_dst, prop_dst, value);
2882 break;
2883 /* TODO: support add/sub, for bitflags? */
2884 default:
2885 BLI_assert_msg(0, "Unsupported RNA override operation on enum");
2886 return false;
2887 }
2888 break;
2889 }
2890 case PROP_POINTER: {
2891 PointerRNA value = RNA_property_pointer_get(ptr_src, prop_src);
2892
2893 switch (override_op) {
2895 RNA_property_pointer_set(ptr_dst, prop_dst, value, nullptr);
2896 break;
2897 default:
2898 BLI_assert_msg(0, "Unsupported RNA override operation on pointer");
2899 return false;
2900 }
2901 break;
2902 }
2903 case PROP_STRING: {
2904 char buff[256];
2905 char *value = RNA_property_string_get_alloc(ptr_src, prop_src, buff, sizeof(buff), nullptr);
2906
2907 switch (override_op) {
2909 RNA_property_string_set(ptr_dst, prop_dst, value);
2910 break;
2911 default:
2912 BLI_assert_msg(0, "Unsupported RNA override operation on string");
2913 return false;
2914 }
2915
2916 if (value != buff) {
2917 MEM_freeN(value);
2918 }
2919 break;
2920 }
2921 case PROP_COLLECTION: {
2922 /* We only support IDProperty-based collection insertion here. */
2923 const bool is_src_idprop = (prop_src->magic != RNA_MAGIC) ||
2924 (prop_src->flag & PROP_IDPROPERTY) != 0;
2925 const bool is_dst_idprop = (prop_dst->magic != RNA_MAGIC) ||
2926 (prop_dst->flag & PROP_IDPROPERTY) != 0;
2927 if (!(is_src_idprop && is_dst_idprop)) {
2928 CLOG_ERROR(&LOG_COMPARE_OVERRIDE,
2929 "'%s': Override operations on RNA collections require a specific override "
2930 "apply callback to be defined.",
2931 rnaapply_ctx.liboverride_property->rna_path);
2932 return false;
2933 }
2934
2935 switch (override_op) {
2937 PointerRNA item_ptr_src, item_ptr_ref, item_ptr_dst;
2938 int item_index_dst;
2939 bool is_valid = false;
2940 if (opop->subitem_local_name != nullptr && opop->subitem_local_name[0] != '\0') {
2941 /* Find from name. */
2942 int item_index_src, item_index_ref;
2944 ptr_src, prop_src, opop->subitem_local_name, &item_ptr_src, &item_index_src) &&
2946 prop_dst,
2948 &item_ptr_ref,
2949 &item_index_ref))
2950 {
2951 is_valid = true;
2952 item_index_dst = item_index_ref + 1;
2953 }
2954 }
2955 if (!is_valid && opop->subitem_local_index >= 0) {
2956 /* Find from index. */
2958 ptr_src, prop_src, opop->subitem_local_index, &item_ptr_src) &&
2960 ptr_dst, prop_dst, opop->subitem_reference_index, &item_ptr_ref))
2961 {
2962 item_index_dst = opop->subitem_reference_index + 1;
2963 is_valid = true;
2964 }
2965 }
2966 if (!is_valid) {
2967 /* Assume it is inserted in first position. */
2968 if (RNA_property_collection_lookup_int(ptr_src, prop_src, 0, &item_ptr_src)) {
2969 item_index_dst = 0;
2970 is_valid = true;
2971 }
2972 }
2973 if (!is_valid) {
2974 return false;
2975 }
2976
2977 RNA_property_collection_add(ptr_dst, prop_dst, &item_ptr_dst);
2978 const int item_index_added = RNA_property_collection_length(ptr_dst, prop_dst) - 1;
2979 BLI_assert(item_index_added >= 0);
2980
2981 /* This is the section of code that makes it specific to IDProperties (the rest could be
2982 * used with some regular RNA/DNA data too, if `RNA_property_collection_add` where
2983 * actually implemented for those).
2984 * Currently it is close to impossible to copy arbitrary 'real' RNA data between
2985 * Collection items. */
2986 IDProperty *item_idprop_src = static_cast<IDProperty *>(item_ptr_src.data);
2987 IDProperty *item_idprop_dst = static_cast<IDProperty *>(item_ptr_dst.data);
2988 IDP_CopyPropertyContent(item_idprop_dst, item_idprop_src);
2989
2990 ret_success = RNA_property_collection_move(
2991 ptr_dst, prop_dst, item_index_added, item_index_dst);
2992 break;
2993 }
2994 default:
2995 BLI_assert_msg(0, "Unsupported RNA override operation on collection");
2996 return false;
2997 }
2998 break;
2999 }
3000 default:
3002 return false;
3003 }
3004
3005 /* Default apply callback always call property update. */
3006 if (ret_success) {
3007 RNA_property_update_main(bmain, nullptr, ptr_dst, prop_dst);
3008 }
3009
3010 return ret_success;
3011}
3012
3013# undef RNA_PROPERTY_GET_SINGLE
3014# undef RNA_PROPERTY_SET_SINGLE
3015
3017
3018/* -------------------------------------------------------------------- */
3021
3022/* Primitive String. */
3023
3024static void rna_PrimitiveString_value_get(PointerRNA *ptr, char *result)
3025{
3026 const PrimitiveStringRNA *data = static_cast<const PrimitiveStringRNA *>(ptr->data);
3027 strcpy(result, data->value ? data->value : "");
3028}
3029
3030static int rna_PrimitiveString_value_length(PointerRNA *ptr)
3031{
3032 const PrimitiveStringRNA *data = static_cast<const PrimitiveStringRNA *>(ptr->data);
3033 return data->value ? strlen(data->value) : 0;
3034}
3035
3036/* Primitive Int. */
3037
3038static int rna_PrimitiveInt_value_get(PointerRNA *ptr)
3039{
3040 const PrimitiveIntRNA *data = static_cast<const PrimitiveIntRNA *>(ptr->data);
3041 return data->value;
3042}
3043
3044/* Primitive Float. */
3045
3046static float rna_PrimitiveFloat_value_get(PointerRNA *ptr)
3047{
3048 const PrimitiveFloatRNA *data = static_cast<const PrimitiveFloatRNA *>(ptr->data);
3049 return data->value;
3050}
3051
3052/* Primitive Boolean. */
3053
3054static bool rna_PrimitiveBoolean_value_get(PointerRNA *ptr)
3055{
3056 const PrimitiveBooleanRNA *data = static_cast<const PrimitiveBooleanRNA *>(ptr->data);
3057 return data->value;
3058}
3059
3061
3062#else
3063
3064static void rna_def_struct(BlenderRNA *brna)
3065{
3066 StructRNA *srna;
3067 PropertyRNA *prop;
3068
3069 srna = RNA_def_struct(brna, "Struct", nullptr);
3070 RNA_def_struct_ui_text(srna, "Struct Definition", "RNA structure definition");
3071 RNA_def_struct_ui_icon(srna, ICON_RNA);
3072
3073 prop = RNA_def_property(srna, "name", PROP_STRING, PROP_NONE);
3075 RNA_def_property_string_funcs(prop, "rna_Struct_name_get", "rna_Struct_name_length", nullptr);
3076 RNA_def_property_ui_text(prop, "Name", "Human readable name");
3077
3078 prop = RNA_def_property(srna, "identifier", PROP_STRING, PROP_NONE);
3081 prop, "rna_Struct_identifier_get", "rna_Struct_identifier_length", nullptr);
3082 RNA_def_property_ui_text(prop, "Identifier", "Unique name used in the code and scripting");
3083 RNA_def_struct_name_property(srna, prop);
3084
3085 prop = RNA_def_property(srna, "description", PROP_STRING, PROP_NONE);
3088 prop, "rna_Struct_description_get", "rna_Struct_description_length", nullptr);
3089 RNA_def_property_ui_text(prop, "Description", "Description of the Struct's purpose");
3090
3091 prop = RNA_def_property(srna, "translation_context", PROP_STRING, PROP_NONE);
3094 "rna_Struct_translation_context_get",
3095 "rna_Struct_translation_context_length",
3096 nullptr);
3098 prop, "Translation Context", "Translation context of the struct's name");
3099
3100 prop = RNA_def_property(srna, "base", PROP_POINTER, PROP_NONE);
3102 RNA_def_property_struct_type(prop, "Struct");
3103 RNA_def_property_pointer_funcs(prop, "rna_Struct_base_get", nullptr, nullptr, nullptr);
3104 RNA_def_property_ui_text(prop, "Base", "Struct definition this is derived from");
3105
3106 prop = RNA_def_property(srna, "nested", PROP_POINTER, PROP_NONE);
3108 RNA_def_property_struct_type(prop, "Struct");
3109 RNA_def_property_pointer_funcs(prop, "rna_Struct_nested_get", nullptr, nullptr, nullptr);
3111 prop,
3112 "Nested",
3113 "Struct in which this struct is always nested, and to which it logically belongs");
3114
3115 prop = RNA_def_property(srna, "name_property", PROP_POINTER, PROP_NONE);
3117 RNA_def_property_struct_type(prop, "StringProperty");
3118 RNA_def_property_pointer_funcs(prop, "rna_Struct_name_property_get", nullptr, nullptr, nullptr);
3119 RNA_def_property_ui_text(prop, "Name Property", "Property that gives the name of the struct");
3120
3121 prop = RNA_def_property(srna, "properties", PROP_COLLECTION, PROP_NONE);
3123 RNA_def_property_struct_type(prop, "Property");
3125 "rna_Struct_properties_begin",
3126 "rna_Struct_properties_next",
3127 "rna_iterator_listbase_end",
3128 "rna_Struct_properties_get",
3129 nullptr,
3130 nullptr,
3131 nullptr,
3132 nullptr);
3133 RNA_def_property_ui_text(prop, "Properties", "Properties in the struct");
3134
3135 prop = RNA_def_property(srna, "functions", PROP_COLLECTION, PROP_NONE);
3137 RNA_def_property_struct_type(prop, "Function");
3139 "rna_Struct_functions_begin",
3140 "rna_Struct_functions_next",
3141 "rna_iterator_listbase_end",
3142 "rna_Struct_functions_get",
3143 nullptr,
3144 nullptr,
3145 nullptr,
3146 nullptr);
3147 RNA_def_property_ui_text(prop, "Functions", "");
3148
3149 prop = RNA_def_property(srna, "property_tags", PROP_COLLECTION, PROP_NONE);
3151 RNA_def_property_struct_type(prop, "EnumPropertyItem");
3153 "rna_Struct_property_tags_begin",
3154 "rna_iterator_array_next",
3155 "rna_iterator_array_end",
3156 "rna_iterator_array_get",
3157 nullptr,
3158 nullptr,
3159 nullptr,
3160 nullptr);
3162 prop, "Property Tags", "Tags that properties can use to influence behavior");
3163}
3164
3166{
3167 StructRNA *srna;
3168 PropertyRNA *prop;
3169 static const EnumPropertyItem dummy_prop_tags[] = {
3170 {0, nullptr, 0, nullptr, nullptr},
3171 };
3172
3173 srna = RNA_def_struct(brna, "Property", nullptr);
3174 RNA_def_struct_ui_text(srna, "Property Definition", "RNA property definition");
3175 RNA_def_struct_refine_func(srna, "rna_Property_refine");
3176 RNA_def_struct_ui_icon(srna, ICON_RNA);
3177
3178 prop = RNA_def_property(srna, "name", PROP_STRING, PROP_NONE);
3181 prop, "rna_Property_name_get", "rna_Property_name_length", nullptr);
3182 RNA_def_property_ui_text(prop, "Name", "Human readable name");
3183
3184 prop = RNA_def_property(srna, "identifier", PROP_STRING, PROP_NONE);
3187 prop, "rna_Property_identifier_get", "rna_Property_identifier_length", nullptr);
3188 RNA_def_property_ui_text(prop, "Identifier", "Unique name used in the code and scripting");
3189 RNA_def_struct_name_property(srna, prop);
3190
3191 prop = RNA_def_property(srna, "description", PROP_STRING, PROP_NONE);
3194 prop, "rna_Property_description_get", "rna_Property_description_length", nullptr);
3195 RNA_def_property_ui_text(prop, "Description", "Description of the property for tooltips");
3196
3197 prop = RNA_def_property(srna, "translation_context", PROP_STRING, PROP_NONE);
3200 "rna_Property_translation_context_get",
3201 "rna_Property_translation_context_length",
3202 nullptr);
3204 prop, "Translation Context", "Translation context of the property's name");
3205
3206 prop = RNA_def_property(srna, "type", PROP_ENUM, PROP_NONE);
3209 RNA_def_property_enum_funcs(prop, "rna_Property_type_get", nullptr, nullptr);
3210 RNA_def_property_ui_text(prop, "Type", "Data type of the property");
3211
3212 prop = RNA_def_property(srna, "subtype", PROP_ENUM, PROP_NONE);
3215 RNA_def_property_enum_funcs(prop, "rna_Property_subtype_get", nullptr, nullptr);
3216 RNA_def_property_ui_text(prop, "Subtype", "Semantic interpretation of the property");
3218
3219 prop = RNA_def_property(srna, "srna", PROP_POINTER, PROP_NONE);
3221 RNA_def_property_struct_type(prop, "Struct");
3222 RNA_def_property_pointer_funcs(prop, "rna_Property_srna_get", nullptr, nullptr, nullptr);
3224 prop, "Base", "Struct definition used for properties assigned to this item");
3225
3226 prop = RNA_def_property(srna, "unit", PROP_ENUM, PROP_NONE);
3230 RNA_def_property_enum_funcs(prop, "rna_Property_unit_get", nullptr, nullptr);
3231 RNA_def_property_ui_text(prop, "Unit", "Type of units for this property");
3232
3233 prop = RNA_def_property(srna, "icon", PROP_ENUM, PROP_NONE);
3236 RNA_def_property_enum_funcs(prop, "rna_Property_icon_get", nullptr, nullptr);
3237 RNA_def_property_ui_text(prop, "Icon", "Icon of the item");
3238
3239 prop = RNA_def_property(srna, "is_readonly", PROP_BOOLEAN, PROP_NONE);
3241 RNA_def_property_boolean_funcs(prop, "rna_Property_readonly_get", nullptr);
3242 RNA_def_property_ui_text(prop, "Read Only", "Property is editable through RNA");
3243
3244 prop = RNA_def_property(srna, "is_animatable", PROP_BOOLEAN, PROP_NONE);
3246 RNA_def_property_boolean_funcs(prop, "rna_Property_animatable_get", nullptr);
3247 RNA_def_property_ui_text(prop, "Animatable", "Property is animatable through RNA");
3248
3249 prop = RNA_def_property(srna, "is_overridable", PROP_BOOLEAN, PROP_NONE);
3251 RNA_def_property_boolean_funcs(prop, "rna_Property_overridable_get", nullptr);
3252 RNA_def_property_ui_text(prop, "Overridable", "Property is overridable through RNA");
3253
3254 prop = RNA_def_property(srna, "is_required", PROP_BOOLEAN, PROP_NONE);
3256 RNA_def_property_boolean_funcs(prop, "rna_Property_is_required_get", nullptr);
3258 prop, "Required", "False when this property is an optional argument in an RNA function");
3259
3260 prop = RNA_def_property(srna, "is_argument_optional", PROP_BOOLEAN, PROP_NONE);
3262 RNA_def_property_boolean_funcs(prop, "rna_Property_is_argument_optional_get", nullptr);
3264 prop,
3265 "Optional Argument",
3266 "True when the property is optional in a Python function implementing an RNA function");
3267
3268 prop = RNA_def_property(srna, "is_never_none", PROP_BOOLEAN, PROP_NONE);
3270 RNA_def_property_boolean_funcs(prop, "rna_Property_is_never_none_get", nullptr);
3271 RNA_def_property_ui_text(prop, "Never None", "True when this value can't be set to None");
3272
3273 prop = RNA_def_property(srna, "is_hidden", PROP_BOOLEAN, PROP_NONE);
3275 RNA_def_property_boolean_funcs(prop, "rna_Property_is_hidden_get", nullptr);
3276 RNA_def_property_ui_text(prop, "Hidden", "True when the property is hidden");
3277
3278 prop = RNA_def_property(srna, "is_skip_save", PROP_BOOLEAN, PROP_NONE);
3280 RNA_def_property_boolean_funcs(prop, "rna_Property_is_skip_save_get", nullptr);
3281 RNA_def_property_ui_text(prop, "Skip Save", "True when the property uses ghost values");
3282
3283 prop = RNA_def_property(srna, "is_skip_preset", PROP_BOOLEAN, PROP_NONE);
3285 RNA_def_property_boolean_funcs(prop, "rna_Property_is_skip_preset_get", nullptr);
3286 RNA_def_property_ui_text(prop, "Skip Preset", "True when the property is not saved in presets");
3287
3288 prop = RNA_def_property(srna, "is_output", PROP_BOOLEAN, PROP_NONE);
3290 RNA_def_property_boolean_funcs(prop, "rna_Property_use_output_get", nullptr);
3292 prop, "Return", "True when this property is an output value from an RNA function");
3293
3294 prop = RNA_def_property(srna, "is_registered", PROP_BOOLEAN, PROP_NONE);
3296 RNA_def_property_boolean_funcs(prop, "rna_Property_is_registered_get", nullptr);
3298 prop, "Registered", "Property is registered as part of type registration");
3299
3300 prop = RNA_def_property(srna, "is_registered_optional", PROP_BOOLEAN, PROP_NONE);
3302 RNA_def_property_boolean_funcs(prop, "rna_Property_is_registered_optional_get", nullptr);
3304 "Registered Optionally",
3305 "Property is optionally registered as part of type registration");
3306
3307 prop = RNA_def_property(srna, "is_runtime", PROP_BOOLEAN, PROP_NONE);
3309 RNA_def_property_boolean_funcs(prop, "rna_Property_is_runtime_get", nullptr);
3310 RNA_def_property_ui_text(prop, "Runtime", "Property has been dynamically created at runtime");
3311
3312 prop = RNA_def_property(srna, "is_enum_flag", PROP_BOOLEAN, PROP_NONE);
3314 RNA_def_property_boolean_funcs(prop, "rna_Property_is_enum_flag_get", nullptr);
3315 RNA_def_property_ui_text(prop, "Enum Flag", "True when multiple enums");
3316
3317 prop = RNA_def_property(srna, "is_library_editable", PROP_BOOLEAN, PROP_NONE);
3319 RNA_def_property_boolean_funcs(prop, "rna_Property_is_library_editable_flag_get", nullptr);
3321 prop, "Library Editable", "Property is editable from linked instances (changes not saved)");
3322
3323 prop = RNA_def_property(srna, "is_path_output", PROP_BOOLEAN, PROP_NONE);
3325 RNA_def_property_boolean_funcs(prop, "rna_Property_is_path_output_flag_get", nullptr);
3327 prop, "Path Output", "Property is a filename, filepath or directory output");
3328
3329 prop = RNA_def_property(srna, "is_path_supports_blend_relative", PROP_BOOLEAN, PROP_NONE);
3332 prop, "rna_Property_is_path_supports_blend_relative_flag_get", nullptr);
3334 prop,
3335 "Path Relative",
3336 "Property is a path which supports the \"//\" prefix, "
3337 "signifying the location as relative to the \".blend\" file's directory");
3338
3339 prop = RNA_def_property(srna, "is_path_supports_templates", PROP_BOOLEAN, PROP_NONE);
3342 prop, "rna_Property_is_path_supports_templates_flag_get", nullptr);
3344 prop,
3345 "Variable Expression Support",
3346 "Property is a path which supports the \"{variable_name}\" variable expression syntax, "
3347 "which substitutes the value of the referenced variable in place of the expression");
3348
3349 prop = RNA_def_property(srna, "tags", PROP_ENUM, PROP_NONE);
3351 RNA_def_property_enum_items(prop, dummy_prop_tags);
3352 RNA_def_property_enum_funcs(prop, "rna_Property_tags_get", nullptr, "rna_Property_tags_itemf");
3355 prop, "Tags", "Subset of tags (defined in parent struct) that are set for this property");
3356}
3357
3359{
3360 StructRNA *srna;
3361 PropertyRNA *prop;
3362
3363 srna = RNA_def_struct(brna, "Function", nullptr);
3364 RNA_def_struct_ui_text(srna, "Function Definition", "RNA function definition");
3365 RNA_def_struct_ui_icon(srna, ICON_RNA);
3366
3367 prop = RNA_def_property(srna, "identifier", PROP_STRING, PROP_NONE);
3370 prop, "rna_Function_identifier_get", "rna_Function_identifier_length", nullptr);
3371 RNA_def_property_ui_text(prop, "Identifier", "Unique name used in the code and scripting");
3372 RNA_def_struct_name_property(srna, prop);
3373
3374 prop = RNA_def_property(srna, "description", PROP_STRING, PROP_NONE);
3377 prop, "rna_Function_description_get", "rna_Function_description_length", nullptr);
3378 RNA_def_property_ui_text(prop, "Description", "Description of the Function's purpose");
3379
3380 prop = RNA_def_property(srna, "parameters", PROP_COLLECTION, PROP_NONE);
3381 // RNA_def_property_clear_flag(prop, PROP_EDITABLE);
3382 RNA_def_property_struct_type(prop, "Property");
3384 "rna_Function_parameters_begin",
3385 "rna_iterator_listbase_next",
3386 "rna_iterator_listbase_end",
3387 "rna_iterator_listbase_get",
3388 nullptr,
3389 nullptr,
3390 nullptr,
3391 nullptr);
3392 RNA_def_property_ui_text(prop, "Parameters", "Parameters for the function");
3393
3394 prop = RNA_def_property(srna, "is_registered", PROP_BOOLEAN, PROP_NONE);
3396 RNA_def_property_boolean_funcs(prop, "rna_Function_registered_get", nullptr);
3398 prop, "Registered", "Function is registered as callback as part of type registration");
3399
3400 prop = RNA_def_property(srna, "is_registered_optional", PROP_BOOLEAN, PROP_NONE);
3402 RNA_def_property_boolean_funcs(prop, "rna_Function_registered_optional_get", nullptr);
3404 prop,
3405 "Registered Optionally",
3406 "Function is optionally registered as callback part of type registration");
3407
3408 prop = RNA_def_property(srna, "use_self", PROP_BOOLEAN, PROP_NONE);
3410 RNA_def_property_boolean_funcs(prop, "rna_Function_no_self_get", nullptr);
3412 prop,
3413 "No Self",
3414 "Function does not pass itself as an argument (becomes a static method in Python)");
3415
3416 prop = RNA_def_property(srna, "use_self_type", PROP_BOOLEAN, PROP_NONE);
3418 RNA_def_property_boolean_funcs(prop, "rna_Function_use_self_type_get", nullptr);
3420 "Use Self Type",
3421 "Function passes itself type as an argument (becomes a class method "
3422 "in Python if use_self is false)");
3423}
3424
3426{
3427 PropertyRNA *prop;
3428
3429 prop = RNA_def_property(srna, "default", type, PROP_NONE);
3431 RNA_def_property_ui_text(prop, "Default", "Default value for this number");
3432
3433 switch (type) {
3434 case PROP_BOOLEAN:
3435 RNA_def_property_boolean_funcs(prop, "rna_BoolProperty_default_get", nullptr);
3436 break;
3437 case PROP_INT:
3438 RNA_def_property_int_funcs(prop, "rna_IntProperty_default_get", nullptr, nullptr);
3439 break;
3440 case PROP_FLOAT:
3441 RNA_def_property_float_funcs(prop, "rna_FloatProperty_default_get", nullptr, nullptr);
3442 break;
3443 default:
3444 break;
3445 }
3446
3447 prop = RNA_def_property(srna, "default_array", type, PROP_NONE);
3449
3450 /* no fixed default length, important its not 0 though. */
3452
3455 prop, "rna_NumberProperty_default_array_get_length"); /* same for all types */
3456
3457 switch (type) {
3458 case PROP_BOOLEAN:
3459 RNA_def_property_boolean_funcs(prop, "rna_BoolProperty_default_array_get", nullptr);
3460 break;
3461 case PROP_INT:
3462 RNA_def_property_int_funcs(prop, "rna_IntProperty_default_array_get", nullptr, nullptr);
3463 break;
3464 case PROP_FLOAT:
3465 RNA_def_property_float_funcs(prop, "rna_FloatProperty_default_array_get", nullptr, nullptr);
3466 break;
3467 default:
3468 break;
3469 }
3470 RNA_def_property_ui_text(prop, "Default Array", "Default value for this array");
3471
3472 prop = RNA_def_property(srna, "array_length", PROP_INT, PROP_UNSIGNED);
3474 RNA_def_property_int_funcs(prop, "rna_Property_array_length_get", nullptr, nullptr);
3475 RNA_def_property_ui_text(prop, "Array Length", "Maximum length of the array, 0 means unlimited");
3476
3477 prop = RNA_def_property(srna, "array_dimensions", PROP_INT, PROP_UNSIGNED);
3480 RNA_def_property_int_funcs(prop, "rna_Property_array_dimensions_get", nullptr, nullptr);
3481 RNA_def_property_ui_text(prop, "Array Dimensions", "Length of each dimension of the array");
3482
3483 prop = RNA_def_property(srna, "is_array", PROP_BOOLEAN, PROP_NONE);
3485 RNA_def_property_boolean_funcs(prop, "rna_NumberProperty_is_array_get", nullptr);
3486 RNA_def_property_ui_text(prop, "Is Array", "");
3487
3488 if (type == PROP_BOOLEAN) {
3489 return;
3490 }
3491
3492 prop = RNA_def_property(srna, "hard_min", type, PROP_NONE);
3494 if (type == PROP_INT) {
3495 RNA_def_property_int_funcs(prop, "rna_IntProperty_hard_min_get", nullptr, nullptr);
3496 }
3497 else {
3498 RNA_def_property_float_funcs(prop, "rna_FloatProperty_hard_min_get", nullptr, nullptr);
3499 }
3500 RNA_def_property_ui_text(prop, "Hard Minimum", "Minimum value used by buttons");
3501
3502 prop = RNA_def_property(srna, "hard_max", type, PROP_NONE);
3504 if (type == PROP_INT) {
3505 RNA_def_property_int_funcs(prop, "rna_IntProperty_hard_max_get", nullptr, nullptr);
3506 }
3507 else {
3508 RNA_def_property_float_funcs(prop, "rna_FloatProperty_hard_max_get", nullptr, nullptr);
3509 }
3510 RNA_def_property_ui_text(prop, "Hard Maximum", "Maximum value used by buttons");
3511
3512 prop = RNA_def_property(srna, "soft_min", type, PROP_NONE);
3514 if (type == PROP_INT) {
3515 RNA_def_property_int_funcs(prop, "rna_IntProperty_soft_min_get", nullptr, nullptr);
3516 }
3517 else {
3518 RNA_def_property_float_funcs(prop, "rna_FloatProperty_soft_min_get", nullptr, nullptr);
3519 }
3520 RNA_def_property_ui_text(prop, "Soft Minimum", "Minimum value used by buttons");
3521
3522 prop = RNA_def_property(srna, "soft_max", type, PROP_NONE);
3524 if (type == PROP_INT) {
3525 RNA_def_property_int_funcs(prop, "rna_IntProperty_soft_max_get", nullptr, nullptr);
3526 }
3527 else {
3528 RNA_def_property_float_funcs(prop, "rna_FloatProperty_soft_max_get", nullptr, nullptr);
3529 }
3530 RNA_def_property_ui_text(prop, "Soft Maximum", "Maximum value used by buttons");
3531
3532 prop = RNA_def_property(srna, "step", type, PROP_UNSIGNED);
3534 if (type == PROP_INT) {
3535 RNA_def_property_int_funcs(prop, "rna_IntProperty_step_get", nullptr, nullptr);
3536 }
3537 else {
3538 RNA_def_property_float_funcs(prop, "rna_FloatProperty_step_get", nullptr, nullptr);
3539 }
3541 prop, "Step", "Step size used by number buttons, for floats 1/100th of the step size");
3542
3543 if (type == PROP_FLOAT) {
3544 prop = RNA_def_property(srna, "precision", PROP_INT, PROP_UNSIGNED);
3546 RNA_def_property_int_funcs(prop, "rna_FloatProperty_precision_get", nullptr, nullptr);
3548 "Precision",
3549 "Number of digits after the dot used by buttons. Fraction is "
3550 "automatically hidden for exact integer values of fields with unit "
3551 "'NONE' or 'TIME' (frame count) and step divisible by 100.");
3552 }
3553}
3554
3556{
3557 PropertyRNA *prop;
3558
3559 prop = RNA_def_property(srna, "default", PROP_STRING, PROP_NONE);
3562 prop, "rna_StringProperty_default_get", "rna_StringProperty_default_length", nullptr);
3563 RNA_def_property_ui_text(prop, "Default", "String default value");
3564
3565 prop = RNA_def_property(srna, "length_max", PROP_INT, PROP_UNSIGNED);
3567 RNA_def_property_int_funcs(prop, "rna_StringProperty_max_length_get", nullptr, nullptr);
3569 prop, "Maximum Length", "Maximum length of the string, 0 means unlimited");
3570}
3571
3573{
3574 PropertyRNA *prop;
3575
3576 prop = RNA_def_property(srna, "default", PROP_ENUM, PROP_NONE);
3580 prop, "rna_EnumProperty_default_get", nullptr, "rna_EnumProperty_default_itemf");
3581 RNA_def_property_ui_text(prop, "Default", "Default value for this enum");
3582
3583 /* same 'default' but uses 'PROP_ENUM_FLAG' */
3584 prop = RNA_def_property(srna, "default_flag", PROP_ENUM, PROP_NONE);
3589 prop, "rna_EnumProperty_default_get", nullptr, "rna_EnumProperty_default_itemf");
3590 RNA_def_property_ui_text(prop, "Default", "Default value for this enum");
3591
3592 prop = RNA_def_property(srna, "enum_items", PROP_COLLECTION, PROP_NONE);
3594 RNA_def_property_struct_type(prop, "EnumPropertyItem");
3596 "rna_EnumProperty_items_begin",
3597 "rna_iterator_array_next",
3598 "rna_iterator_array_end",
3599 "rna_iterator_array_get",
3600 nullptr,
3601 nullptr,
3602 nullptr,
3603 nullptr);
3604 RNA_def_property_ui_text(prop, "Items", "Possible values for the property");
3605
3606 prop = RNA_def_property(srna, "enum_items_static", PROP_COLLECTION, PROP_NONE);
3608 RNA_def_property_struct_type(prop, "EnumPropertyItem");
3610 "rna_EnumProperty_items_begin",
3611 "rna_iterator_array_next",
3612 "rna_iterator_array_end",
3613 "rna_iterator_array_get",
3614 nullptr,
3615 nullptr,
3616 nullptr,
3617 nullptr);
3619 prop,
3620 "Static Items",
3621 "Possible values for the property (never calls optional dynamic generation of those)");
3622
3623 /* Expose a UI version of `enum_items_static` to allow separator & title access,
3624 * needed for the tool-system to access separators from brush enums. */
3625 prop = RNA_def_property(srna, "enum_items_static_ui", PROP_COLLECTION, PROP_NONE);
3627 RNA_def_property_struct_type(prop, "EnumPropertyItem");
3629 "rna_EnumProperty_items_ui_begin",
3630 "rna_iterator_array_next",
3631 "rna_iterator_array_end",
3632 "rna_iterator_array_get",
3633 nullptr,
3634 nullptr,
3635 nullptr,
3636 nullptr);
3638 prop,
3639 "Static Items with UI Elements",
3640 "Possible values for the property (never calls optional dynamic generation of those). "
3641 "Includes UI elements (separators and section headings).");
3642
3643 srna = RNA_def_struct(brna, "EnumPropertyItem", nullptr);
3645 srna, "Enum Item Definition", "Definition of a choice in an RNA enum property");
3646 RNA_def_struct_ui_icon(srna, ICON_RNA);
3647
3648 prop = RNA_def_property(srna, "name", PROP_STRING, PROP_NONE);
3651 prop, "rna_EnumPropertyItem_name_get", "rna_EnumPropertyItem_name_length", nullptr);
3652 RNA_def_property_ui_text(prop, "Name", "Human readable name");
3653
3654 prop = RNA_def_property(srna, "description", PROP_STRING, PROP_NONE);
3657 "rna_EnumPropertyItem_description_get",
3658 "rna_EnumPropertyItem_description_length",
3659 nullptr);
3660 RNA_def_property_ui_text(prop, "Description", "Description of the item's purpose");
3661
3662 prop = RNA_def_property(srna, "identifier", PROP_STRING, PROP_NONE);
3665 "rna_EnumPropertyItem_identifier_get",
3666 "rna_EnumPropertyItem_identifier_length",
3667 nullptr);
3668 RNA_def_property_ui_text(prop, "Identifier", "Unique name used in the code and scripting");
3669 RNA_def_struct_name_property(srna, prop);
3670
3671 prop = RNA_def_property(srna, "value", PROP_INT, PROP_UNSIGNED);
3673 RNA_def_property_int_funcs(prop, "rna_EnumPropertyItem_value_get", nullptr, nullptr);
3674 RNA_def_property_ui_text(prop, "Value", "Value of the item");
3675
3676 prop = RNA_def_property(srna, "icon", PROP_ENUM, PROP_NONE);
3679 RNA_def_property_enum_funcs(prop, "rna_EnumPropertyItem_icon_get", nullptr, nullptr);
3680 RNA_def_property_ui_text(prop, "Icon", "Icon of the item");
3681}
3682
3684{
3685 PropertyRNA *prop;
3686
3687 prop = RNA_def_property(srna, "fixed_type", PROP_POINTER, PROP_NONE);
3689 RNA_def_property_struct_type(prop, "Struct");
3690 if (type == PROP_POINTER) {
3692 prop, "rna_PointerProperty_fixed_type_get", nullptr, nullptr, nullptr);
3693 }
3694 else {
3696 prop, "rna_CollectionProperty_fixed_type_get", nullptr, nullptr, nullptr);
3697 }
3698 RNA_def_property_ui_text(prop, "Pointer Type", "Fixed pointer type, empty if variable type");
3699}
3700
3702{
3703 /* Primitive Values, use when passing #PointerRNA is used for primitive types.
3704 * For the rare cases we want to pass a value as RNA which wraps a primitive data. */
3705
3706 StructRNA *srna;
3707 PropertyRNA *prop;
3708
3709 srna = RNA_def_struct(brna, "PrimitiveString", nullptr);
3710 RNA_def_struct_ui_text(srna, "String Value", "RNA wrapped string");
3711 prop = RNA_def_property(srna, "value", PROP_STRING, PROP_BYTESTRING);
3714 prop, "rna_PrimitiveString_value_get", "rna_PrimitiveString_value_length", nullptr);
3715
3716 srna = RNA_def_struct(brna, "PrimitiveInt", nullptr);
3717 RNA_def_struct_ui_text(srna, "Primitive Int", "RNA wrapped int");
3718 prop = RNA_def_property(srna, "value", PROP_INT, PROP_NONE);
3720 RNA_def_property_int_funcs(prop, "rna_PrimitiveInt_value_get", nullptr, nullptr);
3721
3722 srna = RNA_def_struct(brna, "PrimitiveFloat", nullptr);
3723 RNA_def_struct_ui_text(srna, "Primitive Float", "RNA wrapped float");
3724 prop = RNA_def_property(srna, "value", PROP_FLOAT, PROP_NONE);
3726 RNA_def_property_float_funcs(prop, "rna_PrimitiveFloat_value_get", nullptr, nullptr);
3727
3728 srna = RNA_def_struct(brna, "PrimitiveBoolean", nullptr);
3729 RNA_def_struct_ui_text(srna, "Primitive Boolean", "RNA wrapped boolean");
3730 prop = RNA_def_property(srna, "value", PROP_BOOLEAN, PROP_NONE);
3732 RNA_def_property_boolean_funcs(prop, "rna_PrimitiveBoolean_value_get", nullptr);
3733}
3734
3736{
3737 StructRNA *srna;
3738 PropertyRNA *prop;
3739
3740 /* Struct */
3741 rna_def_struct(brna);
3742
3743 /* Property */
3744 rna_def_property(brna);
3745
3746 /* BoolProperty */
3747 srna = RNA_def_struct(brna, "BoolProperty", "Property");
3748 RNA_def_struct_ui_text(srna, "Boolean Definition", "RNA boolean property definition");
3750
3751 /* IntProperty */
3752 srna = RNA_def_struct(brna, "IntProperty", "Property");
3753 RNA_def_struct_ui_text(srna, "Int Definition", "RNA integer number property definition");
3755
3756 /* FloatProperty */
3757 srna = RNA_def_struct(brna, "FloatProperty", "Property");
3759 "Float Definition",
3760 "RNA floating-point number (single precision) property definition");
3762
3763 /* StringProperty */
3764 srna = RNA_def_struct(brna, "StringProperty", "Property");
3765 RNA_def_struct_ui_text(srna, "String Definition", "RNA text string property definition");
3767
3768 /* EnumProperty */
3769 srna = RNA_def_struct(brna, "EnumProperty", "Property");
3771 srna,
3772 "Enum Definition",
3773 "RNA enumeration property definition, to choose from a number of predefined options");
3774 rna_def_enum_property(brna, srna);
3775
3776 /* PointerProperty */
3777 srna = RNA_def_struct(brna, "PointerProperty", "Property");
3779 srna, "Pointer Definition", "RNA pointer property to point to another RNA struct");
3781
3782 /* CollectionProperty */
3783 srna = RNA_def_struct(brna, "CollectionProperty", "Property");
3785 "Collection Definition",
3786 "RNA collection property to define lists, arrays and mappings");
3788
3789 /* Function */
3790 rna_def_function(brna);
3791
3792 /* Blender RNA */
3793 srna = RNA_def_struct(brna, "BlenderRNA", nullptr);
3794 RNA_def_struct_ui_text(srna, "Blender RNA", "Blender RNA structure definitions");
3795 RNA_def_struct_ui_icon(srna, ICON_RNA);
3796
3797 prop = RNA_def_property(srna, "structs", PROP_COLLECTION, PROP_NONE);
3799 RNA_def_property_struct_type(prop, "Struct");
3801 "rna_BlenderRNA_structs_begin",
3802 "rna_iterator_listbase_next",
3803 "rna_iterator_listbase_end",
3804 "rna_iterator_listbase_get",
3805/* included for speed, can be removed */
3806# if 0
3807 nullptr,
3808 nullptr,
3809 nullptr,
3810 nullptr);
3811# else
3812 "rna_BlenderRNA_structs_length",
3813 "rna_BlenderRNA_structs_lookup_int",
3814 "rna_BlenderRNA_structs_lookup_string",
3815 nullptr);
3816# endif
3817
3818 RNA_def_property_ui_text(prop, "Structs", "");
3819
3821}
3822
3823#endif
void IDP_CopyPropertyContent(IDProperty *dst, const IDProperty *src) ATTR_NONNULL()
Definition idprop.cc:878
void BKE_lib_override_library_operations_tag(IDOverrideLibraryProperty *liboverride_property, short tag, bool do_set)
void BKE_lib_override_library_property_operation_delete(IDOverrideLibraryProperty *liboverride_property, IDOverrideLibraryPropertyOperation *liboverride_property_operation)
IDOverrideLibraryProperty * BKE_lib_override_library_property_find(IDOverrideLibrary *liboverride, const char *rna_path)
IDOverrideLibraryProperty * BKE_lib_override_library_property_get(IDOverrideLibrary *liboverride, const char *rna_path, bool *r_created)
IDOverrideLibraryPropertyOperation * BKE_lib_override_library_property_operation_get(IDOverrideLibraryProperty *liboverride_property, short operation, const char *subitem_refname, const char *subitem_locname, const std::optional< ID * > &subitem_refid, const std::optional< ID * > &subitem_locid, int subitem_refindex, int subitem_locindex, bool strict, bool *r_strict, bool *r_created)
#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
void * BLI_ghash_lookup(const GHash *gh, const void *key) ATTR_WARN_UNUSED_RESULT
Definition BLI_ghash.cc:731
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_MUTABLE(type, var, list)
int BLI_listbase_count(const ListBase *listbase) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
Definition listbase.cc:524
size_t BLI_str_escape(char *__restrict dst, const char *__restrict src, size_t dst_maxncpy) ATTR_NONNULL(1
unsigned int uint
#define UNUSED_VARS_NDEBUG(...)
#define UNLIKELY(x)
#define ELEM(...)
#define STREQ(a, b)
#define BLT_I18NCONTEXT_UNIT
#define CLOG_ERROR(clg_ref,...)
Definition CLG_log.h:182
#define CLOG_WARN(clg_ref,...)
Definition CLG_log.h:181
#define CLOG_INFO(clg_ref, level,...)
Definition CLG_log.h:179
@ LIBOVERRIDE_PROP_OP_TAG_UNUSED
Definition DNA_ID.h:284
@ LIBOVERRIDE_OP_FLAG_IDPOINTER_MATCH_REFERENCE
Definition DNA_ID.h:246
struct ID ID
@ ID_TAG_LIBOVERRIDE_NEED_RESYNC
Definition DNA_ID.h:814
@ LIBOVERRIDE_OP_ADD
Definition DNA_ID.h:223
@ LIBOVERRIDE_OP_SUBTRACT
Definition DNA_ID.h:225
@ LIBOVERRIDE_OP_REPLACE
Definition DNA_ID.h:220
@ LIBOVERRIDE_OP_MULTIPLY
Definition DNA_ID.h:227
@ LIBOVERRIDE_OP_INSERT_BEFORE
Definition DNA_ID.h:231
@ LIBOVERRIDE_OP_INSERT_AFTER
Definition DNA_ID.h:230
@ IDP_FLAG_OVERRIDABLE_LIBRARY
Read Guarded memory(de)allocation.
eRNAOverrideMatch
@ RNA_OVERRIDE_COMPARE_CREATE
eRNACompareMode
@ RNA_OVERRIDE_MATCH_RESULT_CREATED
#define RNA_MAX_ARRAY_DIMENSION
Definition RNA_define.hh:26
@ PARM_PYFUNC_REGISTER_OPTIONAL
Definition RNA_types.hh:523
@ 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
#define RNA_STACK_ARRAY
Definition RNA_types.hh:214
@ FUNC_USE_SELF_TYPE
Definition RNA_types.hh:800
@ FUNC_BUILTIN
Definition RNA_types.hh:824
@ FUNC_NO_SELF
Definition RNA_types.hh:798
@ FUNC_REGISTER
Definition RNA_types.hh:812
@ FUNC_REGISTER_OPTIONAL
Definition RNA_types.hh:814
@ STRUCT_PUBLIC_NAMESPACE
Definition RNA_types.hh:860
@ STRUCT_ID
Definition RNA_types.hh:844
@ PROP_STRING_SEARCH_SUGGESTION
Definition RNA_types.hh:701
@ PROP_STRING_SEARCH_SORT
Definition RNA_types.hh:694
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
@ PROP_UNIT_VOLUME
Definition RNA_types.hh:164
@ PROP_UNIT_POWER
Definition RNA_types.hh:172
@ PROP_UNIT_ROTATION
Definition RNA_types.hh:166
@ PROP_UNIT_FREQUENCY
Definition RNA_types.hh:176
@ PROP_UNIT_WAVELENGTH
Definition RNA_types.hh:174
@ PROP_UNIT_VELOCITY
Definition RNA_types.hh:169
@ PROP_UNIT_LENGTH
Definition RNA_types.hh:162
@ PROP_UNIT_NONE
Definition RNA_types.hh:161
@ PROP_UNIT_ACCELERATION
Definition RNA_types.hh:170
@ PROP_UNIT_AREA
Definition RNA_types.hh:163
@ PROP_UNIT_TIME
Definition RNA_types.hh:167
@ PROP_UNIT_CAMERA
Definition RNA_types.hh:171
@ PROP_UNIT_TEMPERATURE
Definition RNA_types.hh:173
@ PROP_UNIT_MASS
Definition RNA_types.hh:165
@ PROP_UNIT_TIME_ABSOLUTE
Definition RNA_types.hh:168
@ PROP_UNIT_COLOR_TEMPERATURE
Definition RNA_types.hh:175
@ PROPOVERRIDE_OVERRIDABLE_LIBRARY
Definition RNA_types.hh:469
@ PROPOVERRIDE_LIBRARY_INSERTION
Definition RNA_types.hh:494
@ PROPOVERRIDE_NO_PROP_NAME
Definition RNA_types.hh:502
@ PROP_PATH_OUTPUT
Definition RNA_types.hh:425
@ PROP_DYNAMIC
Definition RNA_types.hh:402
@ PROP_ANIMATABLE
Definition RNA_types.hh:305
@ PROP_PROPORTIONAL
Definition RNA_types.hh:335
@ PROP_PATH_SUPPORTS_BLEND_RELATIVE
Definition RNA_types.hh:430
@ PROP_EDITABLE
Definition RNA_types.hh:292
@ PROP_ENUM_FLAG
Definition RNA_types.hh:378
@ PROP_LIB_EXCEPTION
Definition RNA_types.hh:298
@ PROP_REGISTER_OPTIONAL
Definition RNA_types.hh:386
@ PROP_NEVER_NULL
Definition RNA_types.hh:351
@ PROP_PATH_SUPPORTS_TEMPLATES
Definition RNA_types.hh:443
@ PROP_REGISTER
Definition RNA_types.hh:385
@ PROP_PTR_NO_OWNERSHIP
Definition RNA_types.hh:369
@ PROP_SKIP_SAVE
Definition RNA_types.hh:330
@ PROP_SKIP_PRESET
Definition RNA_types.hh:446
@ PROP_TEXTEDIT_UPDATE
Definition RNA_types.hh:312
@ PROP_HIDDEN
Definition RNA_types.hh:324
@ PROP_IDPROPERTY
Definition RNA_types.hh:400
@ PROP_BYTESTRING
Definition RNA_types.hh:228
@ PROP_NONE
Definition RNA_types.hh:221
@ PROP_UNSIGNED
Definition RNA_types.hh:237
#define C
Definition RandGen.cpp:29
BMesh const char void * data
#define printf(...)
float length(VecOp< float, D >) RET
#define ID_IS_OVERRIDE_LIBRARY_VIRTUAL(_id)
#define ID_IS_OVERRIDE_LIBRARY(_id)
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
float RNA_property_float_get(PointerRNA *ptr, PropertyRNA *prop)
bool RNA_property_is_runtime(const PropertyRNA *prop)
void RNA_property_float_get_default_array(PointerRNA *ptr, PropertyRNA *prop, float *values)
const char * RNA_property_ui_name_raw(const PropertyRNA *prop)
bool RNA_property_array_check(PropertyRNA *prop)
void RNA_property_float_get_array(PointerRNA *ptr, PropertyRNA *prop, float *values)
bool RNA_struct_is_ID(const StructRNA *type)
void RNA_property_float_set_index(PointerRNA *ptr, PropertyRNA *prop, int index, float value)
void rna_iterator_listbase_end(CollectionPropertyIterator *)
PropertyUnit RNA_property_unit(PropertyRNA *prop)
int RNA_property_ui_icon(const PropertyRNA *prop)
void rna_iterator_array_begin(CollectionPropertyIterator *iter, PointerRNA *ptr, void *data, int itemsize, int length, bool free_ptr, IteratorSkipFunc skip)
StructRNA * RNA_property_pointer_type(PointerRNA *ptr, PropertyRNA *prop)
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)
const EnumPropertyItem * RNA_struct_property_tag_defines(const StructRNA *type)
uint RNA_enum_items_count(const EnumPropertyItem *item)
const char * RNA_property_ui_description_raw(const PropertyRNA *prop)
void RNA_property_collection_begin(PointerRNA *ptr, PropertyRNA *prop, CollectionPropertyIterator *iter)
void RNA_property_float_range(PointerRNA *ptr, PropertyRNA *prop, float *hardmin, float *hardmax)
void RNA_property_boolean_get_array(PointerRNA *ptr, PropertyRNA *prop, bool *values)
PropertyType RNA_property_type(PropertyRNA *prop)
const PointerRNA PointerRNA_NULL
char * RNA_property_string_get_alloc(PointerRNA *ptr, PropertyRNA *prop, char *fixedbuf, int fixedlen, int *r_len)
void RNA_property_enum_set(PointerRNA *ptr, PropertyRNA *prop, int value)
PointerRNA RNA_property_pointer_get(PointerRNA *ptr, PropertyRNA *prop)
IDProperty * RNA_struct_idprops(PointerRNA *ptr, bool create)
bool RNA_property_boolean_get(PointerRNA *ptr, PropertyRNA *prop)
void RNA_property_boolean_get_default_array(PointerRNA *ptr, PropertyRNA *prop, bool *values)
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_property_update_main(Main *bmain, Scene *scene, PointerRNA *ptr, PropertyRNA *prop)
void rna_iterator_listbase_next(CollectionPropertyIterator *iter)
bool RNA_property_collection_lookup_int(PointerRNA *ptr, PropertyRNA *prop, int key, PointerRNA *r_ptr)
void RNA_property_collection_add(PointerRNA *ptr, PropertyRNA *prop, PointerRNA *r_ptr)
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)
int RNA_property_enum_get(PointerRNA *ptr, PropertyRNA *prop)
PropertyRNA * RNA_struct_name_property(const StructRNA *type)
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)
PropertySubType RNA_property_subtype(PropertyRNA *prop)
void RNA_property_int_range(PointerRNA *ptr, PropertyRNA *prop, int *hardmin, int *hardmax)
int RNA_property_tags(PropertyRNA *prop)
void RNA_property_collection_end(CollectionPropertyIterator *iter)
PointerRNA RNA_pointer_create_discrete(ID *id, StructRNA *type, void *data)
IDProperty * rna_idproperty_check(PropertyRNA **prop, PointerRNA *ptr)
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)
const char * RNA_property_identifier(const PropertyRNA *prop)
PropertyRNA * rna_ensure_property(PropertyRNA *prop)
int RNA_property_collection_length(PointerRNA *ptr, PropertyRNA *prop)
void RNA_property_boolean_set_array(PointerRNA *ptr, PropertyRNA *prop, const bool *values)
void RNA_property_string_set(PointerRNA *ptr, PropertyRNA *prop, const char *value)
bool RNA_struct_equals(Main *bmain, PointerRNA *ptr_a, PointerRNA *ptr_b, eRNACompareMode mode)
#define RNA_PATH_BUFFSIZE
bool RNA_struct_override_matches(Main *bmain, PointerRNA *ptr_local, PointerRNA *ptr_reference, const char *root_path, const size_t root_path_len, IDOverrideLibrary *liboverride, const eRNAOverrideMatch flags, eRNAOverrideMatchResult *r_report_flags)
void RNA_def_struct_name_property(StructRNA *srna, PropertyRNA *prop)
void RNA_def_struct_refine_func(StructRNA *srna, const char *refine)
void RNA_def_property_string_funcs(PropertyRNA *prop, const char *get, const char *length, const char *set)
void RNA_def_property_float_funcs(PropertyRNA *prop, const char *get, const char *set, const char *range)
void RNA_def_property_ui_text(PropertyRNA *prop, const char *name, const char *description)
void RNA_def_property_collection_funcs(PropertyRNA *prop, const char *begin, const char *next, const char *end, const char *get, const char *length, const char *lookupint, const char *lookupstring, const char *assignint)
void RNA_def_struct_ui_text(StructRNA *srna, const char *name, const char *description)
void RNA_def_property_boolean_funcs(PropertyRNA *prop, const char *get, const char *set)
void RNA_def_property_dynamic_array_funcs(PropertyRNA *prop, const char *getlength)
void RNA_def_property_enum_items(PropertyRNA *prop, const EnumPropertyItem *item)
void RNA_def_property_array(PropertyRNA *prop, int length)
void RNA_def_property_struct_type(PropertyRNA *prop, const char *type)
PropertyRNA * RNA_def_property(StructOrFunctionRNA *cont_, const char *identifier, int type, int subtype)
void RNA_def_property_enum_funcs(PropertyRNA *prop, const char *get, const char *set, const char *item)
StructRNA * RNA_def_struct(BlenderRNA *brna, const char *identifier, const char *from)
void RNA_enum_item_end(EnumPropertyItem **items, int *totitem)
void RNA_def_property_clear_flag(PropertyRNA *prop, PropertyFlag flag)
void RNA_def_property_pointer_funcs(PropertyRNA *prop, const char *get, const char *set, const char *type_fn, const char *poll)
void RNA_enum_item_add(EnumPropertyItem **items, int *totitem, const EnumPropertyItem *item)
void RNA_def_property_int_funcs(PropertyRNA *prop, const char *get, const char *set, const char *range)
void RNA_def_struct_ui_icon(StructRNA *srna, int icon)
void RNA_def_property_translation_context(PropertyRNA *prop, const char *context)
void RNA_def_property_flag(PropertyRNA *prop, PropertyFlag flag)
bool rna_property_override_apply_default(Main *bmain, RNAPropertyOverrideApplyContext &rnaapply_ctx)
void rna_property_override_diff_default(Main *bmain, RNAPropertyOverrideDiffContext &rnadiff_ctx)
void rna_builtin_properties_next(CollectionPropertyIterator *iter)
void rna_builtin_properties_begin(CollectionPropertyIterator *iter, PointerRNA *ptr)
PointerRNA rna_builtin_properties_get(CollectionPropertyIterator *iter)
PointerRNA rna_builtin_type_get(PointerRNA *ptr)
bool rna_builtin_properties_lookup_string(PointerRNA *ptr, const char *key, PointerRNA *r_ptr)
bool rna_property_override_store_default(Main *bmain, PointerRNA *ptr_local, PointerRNA *ptr_reference, PointerRNA *ptr_storage, PropertyRNA *prop_local, PropertyRNA *prop_reference, PropertyRNA *prop_storage, int len_local, int len_reference, int len_storage, IDOverrideLibraryPropertyOperation *opop)
#define RNA_MAGIC
@ PROP_INTERN_BUILTIN
std::optional< std::string > RNA_path_from_ID_to_property(const PointerRNA *ptr, PropertyRNA *prop)
Definition rna_path.cc:1173
void RNA_def_rna(BlenderRNA *brna)
Definition rna_rna.cc:3735
const EnumPropertyItem rna_enum_property_type_items[]
Definition rna_rna.cc:43
const EnumPropertyItem rna_enum_property_override_flag_collection_items[]
Definition rna_rna.cc:237
static void rna_def_pointer_property(StructRNA *srna, PropertyType type)
Definition rna_rna.cc:3683
const EnumPropertyItem rna_enum_dummy_NULL_items[]
Definition rna_rna.cc:26
const EnumPropertyItem rna_enum_property_subtype_number_array_items[]
Definition rna_rna.cc:117
static constexpr auto PROP_HIDDEN_DESCR
Definition rna_rna.cc:160
static constexpr auto PROP_PATH_RELATIVE_DESCR
Definition rna_rna.cc:175
static constexpr auto PROP_ENUM_FLAG_DESCR
Definition rna_rna.cc:181
static void rna_def_rna_primitive(BlenderRNA *brna)
Definition rna_rna.cc:3701
static void rna_def_number_property(StructRNA *srna, PropertyType type)
Definition rna_rna.cc:3425
static void rna_def_enum_property(BlenderRNA *brna, StructRNA *srna)
Definition rna_rna.cc:3572
static void rna_def_property(BlenderRNA *brna)
Definition rna_rna.cc:3165
const EnumPropertyItem rna_enum_property_unit_items[]
Definition rna_rna.cc:139
const EnumPropertyItem rna_enum_property_subtype_number_items[]
Definition rna_rna.cc:110
static void rna_def_string_property(StructRNA *srna)
Definition rna_rna.cc:3555
const EnumPropertyItem rna_enum_property_string_search_flag_items[]
Definition rna_rna.cc:252
#define RNA_ENUM_PROPERTY_SUBTYPE_STRING_ITEMS
Definition rna_rna.cc:58
const EnumPropertyItem rna_enum_property_override_flag_items[]
Definition rna_rna.cc:232
static void rna_def_struct(BlenderRNA *brna)
Definition rna_rna.cc:3064
static constexpr auto PROP_ANIMATABLE_DESCR
Definition rna_rna.cc:168
const EnumPropertyItem rna_enum_property_subtype_items[]
Definition rna_rna.cc:124
static constexpr auto PROP_TEXTEDIT_UPDATE_DESCR
Definition rna_rna.cc:173
static constexpr auto PROP_PROPORTIONAL_DESCR
Definition rna_rna.cc:172
static constexpr auto PROP_PATH_SUPPORTS_TEMPLATES_DESCR
Definition rna_rna.cc:178
const EnumPropertyItem rna_enum_property_subtype_string_items[]
Definition rna_rna.cc:103
static constexpr auto PROP_SKIP_PRESET_DESCR
Definition rna_rna.cc:167
const EnumPropertyItem rna_enum_dummy_DEFAULT_items[]
Definition rna_rna.cc:32
#define RNA_ENUM_PROPERTY_SUBTYPE_NUMBER_ARRAY_ITEMS
Definition rna_rna.cc:83
static const EnumPropertyItem rna_enum_property_item_library_overridable
Definition rna_rna.cc:223
static void rna_def_function(BlenderRNA *brna)
Definition rna_rna.cc:3358
static constexpr auto PROP_SKIP_SAVE_DESCR
Definition rna_rna.cc:163
static constexpr auto PROP_PATH_OUTPUT_DESCR
Definition rna_rna.cc:174
const EnumPropertyItem rna_enum_property_flag_items[]
Definition rna_rna.cc:183
#define RNA_ENUM_PROPERTY_SUBTYPE_NUMBER_ITEMS
Definition rna_rna.cc:65
const EnumPropertyItem rna_enum_property_flag_enum_items[]
Definition rna_rna.cc:214
static constexpr auto PROP_LIB_EXCEPTION_DESCR
Definition rna_rna.cc:169
const EnumPropertyItem rna_enum_icon_items[]
Definition rna_ui_api.cc:25
unsigned int structs_len
union CollectionPropertyIterator::@251313231040372062304153161337117373343066046335 internal
ListBaseIterator listbase
Definition RNA_types.hh:572
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
PropEnumItemFunc item_fn
unsigned int rna_prop_type
Definition DNA_ID.h:278
struct ID * reference
Definition DNA_ID.h:324
ListBase group
Definition DNA_ID.h:138
short flag
Definition DNA_ID.h:153
char name[64]
Definition DNA_ID.h:154
IDPropertyData data
Definition DNA_ID.h:159
Definition DNA_ID.h:404
int tag
Definition DNA_ID.h:424
IDOverrideLibrary * override_library
Definition DNA_ID.h:459
char name[66]
Definition DNA_ID.h:415
void * first
ID * owner_id
Definition RNA_types.hh:51
StructRNA * type
Definition RNA_types.hh:52
void * data
Definition RNA_types.hh:53
RNAPropOverrideApply override_apply
unsigned int arraydimension
PropertyRNA * next
const char * name
unsigned int totarraylength
const char * identifier
IDOverrideLibraryProperty * liboverride_property
IDOverrideLibraryPropertyOperation * liboverride_operation
eRNAOverrideMatchResult report_flag
ContainerRNA cont
StructRNA * base
i
Definition text_draw.cc:230
PointerRNA * ptr
Definition wm_files.cc:4227