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