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