Blender V5.0
anim_rna.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2023 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
8
9#include <fmt/format.h>
10
11#include "ANIM_rna.hh"
12
13#include "BLI_listbase.h"
14#include "BLI_string.h"
15#include "BLI_vector.hh"
16
17#include "DNA_object_types.h"
18
19#include "RNA_access.hh"
20#include "RNA_path.hh"
21#include "RNA_prototypes.hh"
22
23namespace blender::animrig {
24
26{
27 Vector<float> values;
28 if (RNA_property_array_check(prop)) {
29 const int length = RNA_property_array_length(ptr, prop);
30
31 switch (RNA_property_type(prop)) {
32 case PROP_BOOLEAN: {
33 bool *tmp_bool = MEM_malloc_arrayN<bool>(length, __func__);
34 RNA_property_boolean_get_array(ptr, prop, tmp_bool);
35 for (int i = 0; i < length; i++) {
36 values.append(float(tmp_bool[i]));
37 }
38 MEM_freeN(tmp_bool);
39 break;
40 }
41 case PROP_INT: {
42 int *tmp_int = MEM_malloc_arrayN<int>(length, __func__);
43 RNA_property_int_get_array(ptr, prop, tmp_int);
44 for (int i = 0; i < length; i++) {
45 values.append(float(tmp_int[i]));
46 }
47 MEM_freeN(tmp_int);
48 break;
49 }
50 case PROP_FLOAT: {
51 values.reinitialize(length);
52 RNA_property_float_get_array(ptr, prop, values.data());
53 break;
54 }
55 default:
56 values.reinitialize(length);
57 break;
58 }
59 }
60 else {
61 switch (RNA_property_type(prop)) {
62 case PROP_BOOLEAN:
63 values.append(float(RNA_property_boolean_get(ptr, prop)));
64 break;
65 case PROP_INT:
66 values.append(float(RNA_property_int_get(ptr, prop)));
67 break;
68 case PROP_FLOAT:
69 values.append(RNA_property_float_get(ptr, prop));
70 break;
71 case PROP_ENUM:
72 values.append(float(RNA_property_enum_get(ptr, prop)));
73 break;
74 default:
75 values.append(0.0f);
76 }
77 }
78
79 return values;
80}
81
83{
84 switch (rotation_mode) {
85 case ROT_MODE_QUAT:
86 return "rotation_quaternion";
88 return "rotation_axis_angle";
89 default:
90 return "rotation_euler";
91 }
92}
93
94static bool is_idproperty_keyable(const IDProperty *id_prop, PointerRNA *ptr, PropertyRNA *prop)
95{
96 /* While you can cast the IDProperty* to a PropertyRNA* and pass it to the RNA_* functions, this
97 * does not work because it will not have the right flags set. Instead the resolved
98 * PointerRNA and PropertyRNA need to be passed. */
99 if (!RNA_property_anim_editable(ptr, prop)) {
100 return false;
101 }
102
103 if (ELEM(id_prop->type,
104 eIDPropertyType::IDP_BOOLEAN,
105 eIDPropertyType::IDP_INT,
106 eIDPropertyType::IDP_FLOAT,
107 eIDPropertyType::IDP_DOUBLE))
108 {
109 return true;
110 }
111
112 if (id_prop->type == eIDPropertyType::IDP_ARRAY) {
113 if (ELEM(id_prop->subtype,
114 eIDPropertyType::IDP_BOOLEAN,
115 eIDPropertyType::IDP_INT,
116 eIDPropertyType::IDP_FLOAT,
117 eIDPropertyType::IDP_DOUBLE))
118 {
119 return true;
120 }
121 }
122
123 return false;
124}
125
127{
128 IDProperty *properties;
129
130 if (ptr.type == &RNA_PoseBone) {
131 const bPoseChannel *pchan = static_cast<bPoseChannel *>(ptr.data);
132 properties = pchan->prop;
133 }
134 else if (ptr.type == &RNA_Object) {
135 const Object *ob = static_cast<Object *>(ptr.data);
136 properties = ob->id.properties;
137 }
138 else {
139 /* Pointer type not supported. */
140 return {};
141 }
142
143 if (!properties) {
144 return {};
145 }
146
148 LISTBASE_FOREACH (const IDProperty *, id_prop, &properties->data.group) {
149 PointerRNA resolved_ptr;
150 PropertyRNA *resolved_prop;
151 std::string path = id_prop->name;
152 /* Resolving the path twice, once as RNA property (without brackets, `"propname"`),
153 * and once as ID property (with brackets, `["propname"]`).
154 * This is required to support IDProperties that have been defined as part of an add-on.
155 * Those need to be animated through an RNA path without the brackets. */
156 bool is_resolved = RNA_path_resolve_property(
157 &ptr, path.c_str(), &resolved_ptr, &resolved_prop);
158 /* ID properties can be named the same as internal properties, for example `scale`. In that
159 * case they would resolve, but it wouldn't be the correct property. `RNA_property_is_runtime`
160 * catches that case. */
161 if (!is_resolved || !RNA_property_is_runtime(resolved_prop)) {
162 char name_escaped[MAX_IDPROP_NAME * 2];
163 BLI_str_escape(name_escaped, id_prop->name, sizeof(name_escaped));
164 path = fmt::format("[\"{}\"]", name_escaped);
165 is_resolved = RNA_path_resolve_property(&ptr, path.c_str(), &resolved_ptr, &resolved_prop);
166 }
167 if (!is_resolved) {
168 continue;
169 }
170 if (is_idproperty_keyable(id_prop, &resolved_ptr, resolved_prop)) {
171 paths.append({path});
172 }
173 }
174 return paths;
175}
176
177} // namespace blender::animrig
Helper functions for animation to interact with the RNA system.
#define LISTBASE_FOREACH(type, var, list)
size_t BLI_str_escape(char *__restrict dst, const char *__restrict src, size_t dst_maxncpy) ATTR_NONNULL(1
#define ELEM(...)
#define MAX_IDPROP_NAME
Definition DNA_ID.h:186
eRotationModes
@ ROT_MODE_QUAT
@ ROT_MODE_AXISANGLE
Object is a sort of wrapper for general info.
@ PROP_FLOAT
Definition RNA_types.hh:164
@ PROP_BOOLEAN
Definition RNA_types.hh:162
@ PROP_ENUM
Definition RNA_types.hh:166
@ PROP_INT
Definition RNA_types.hh:163
void append(const T &value)
void reinitialize(const int64_t new_size)
float length(VecOp< float, D >) RET
void * MEM_malloc_arrayN(size_t len, size_t size, const char *str)
Definition mallocn.cc:133
void MEM_freeN(void *vmemh)
Definition mallocn.cc:113
static bool is_idproperty_keyable(const IDProperty *id_prop, PointerRNA *ptr, PropertyRNA *prop)
Definition anim_rna.cc:94
Vector< RNAPath > get_keyable_id_property_paths(const PointerRNA &ptr)
Definition anim_rna.cc:126
Vector< float > get_rna_values(PointerRNA *ptr, PropertyRNA *prop)
Definition anim_rna.cc:25
StringRef get_rotation_mode_path(eRotationModes rotation_mode)
Definition anim_rna.cc:82
float RNA_property_float_get(PointerRNA *ptr, PropertyRNA *prop)
bool RNA_property_is_runtime(const PropertyRNA *prop)
bool RNA_property_array_check(PropertyRNA *prop)
void RNA_property_float_get_array(PointerRNA *ptr, PropertyRNA *prop, float *values)
void RNA_property_boolean_get_array(PointerRNA *ptr, PropertyRNA *prop, bool *values)
PropertyType RNA_property_type(PropertyRNA *prop)
bool RNA_property_boolean_get(PointerRNA *ptr, PropertyRNA *prop)
int RNA_property_int_get(PointerRNA *ptr, PropertyRNA *prop)
bool RNA_property_anim_editable(const PointerRNA *ptr, PropertyRNA *prop_orig)
int RNA_property_array_length(PointerRNA *ptr, PropertyRNA *prop)
int RNA_property_enum_get(PointerRNA *ptr, PropertyRNA *prop)
void RNA_property_int_get_array(PointerRNA *ptr, PropertyRNA *prop, int *values)
bool RNA_path_resolve_property(const PointerRNA *ptr, const char *path, PointerRNA *r_ptr, PropertyRNA **r_prop)
Definition rna_path.cc:560
ListBase group
Definition DNA_ID.h:143
IDPropertyData data
Definition DNA_ID.h:169
char subtype
Definition DNA_ID.h:161
char type
Definition DNA_ID.h:156
IDProperty * properties
Definition DNA_ID.h:480
const char * name
IDProperty * prop
i
Definition text_draw.cc:230
PointerRNA * ptr
Definition wm_files.cc:4238