26#include "RNA_prototypes.hh"
33#include "testing/testing.h"
121 strip->
start = -10.0;
186 object->empty_drawsize = 42.0;
190 {{
"empty_display_size"}},
196 ASSERT_NE(
nullptr, object->adt);
197 ASSERT_NE(
nullptr, object->adt->action);
198 Action &action =
object->adt->action->wrap();
202 ASSERT_EQ(1, action.
slots().size());
204 EXPECT_STREQ(object->id.name, slot->
identifier);
205 EXPECT_STREQ(object->adt->last_slot_identifier, slot->
identifier);
210 ASSERT_EQ(1, action.
layers().size());
212 EXPECT_TRUE(strlen(action.
layer(0)->
name) > 0);
215 ASSERT_EQ(Strip::Type::Keyframe, strip->
type());
220 ASSERT_NE(
nullptr, channelbag);
223 EXPECT_EQ(1, channelbag->fcurves().size());
224 const FCurve *fcurve = channelbag->fcurve_find({
"empty_display_size", 0});
225 ASSERT_NE(
nullptr, fcurve);
226 ASSERT_NE(
nullptr, fcurve->
bezt);
233 object->empty_drawsize = 86.0;
237 {{
"empty_display_size"}},
248 object->empty_drawsize = 7.0;
252 {{
"empty_display_size"}},
270 &armature_object_rna_pointer,
279 ASSERT_TRUE(armature_object->adt !=
nullptr);
280 ASSERT_TRUE(armature_object->adt->action !=
nullptr);
285 &armature_rna_pointer,
293 ASSERT_TRUE(armature->adt !=
nullptr);
294 ASSERT_TRUE(armature->adt->action !=
nullptr);
297 ASSERT_EQ(armature->adt->action, armature_object->adt->action);
299 Action &action = armature->adt->action->wrap();
303 ASSERT_TRUE(slot->idtype ==
ID_AR || slot->idtype ==
ID_OB);
313 &material_rna_pointer,
322 ASSERT_TRUE(material->adt !=
nullptr);
323 ASSERT_TRUE(material->adt->action !=
nullptr);
335 ASSERT_TRUE(cube->adt !=
nullptr);
336 ASSERT_TRUE(cube->adt->action !=
nullptr);
339 ASSERT_NE(cube->adt->action, material->adt->action);
342 &cube_mesh_rna_pointer,
344 {{
"remesh_voxel_size"}},
351 ASSERT_TRUE(cube_mesh->adt !=
nullptr);
352 ASSERT_TRUE(cube_mesh->adt->action !=
nullptr);
355 ASSERT_EQ(cube_mesh->adt->action, cube->adt->action);
357 ASSERT_NE(cube_mesh->adt->action, material->adt->action);
359 Action &action = cube->adt->action->wrap();
364 ASSERT_EQ(material->adt->action->wrap().slot_array_num, 1);
367 ASSERT_TRUE(slot->idtype ==
ID_ME || slot->idtype ==
ID_OB);
368 ASSERT_NE(slot->idtype,
ID_MA);
393 ASSERT_TRUE(cube->adt !=
nullptr);
394 ASSERT_TRUE(cube->adt->action !=
nullptr);
397 &cube_mesh_rna_pointer,
399 {{
"remesh_voxel_size"}},
406 ASSERT_TRUE(cube_mesh->adt !=
nullptr);
407 ASSERT_TRUE(cube_mesh->adt->action !=
nullptr);
410 ASSERT_NE(cube->adt->action, cube_mesh->adt->action);
413 &another_object_rna_pointer,
422 ASSERT_TRUE(another_object->
adt !=
nullptr);
423 ASSERT_TRUE(another_object->
adt->
action !=
nullptr);
427 ASSERT_NE(cube->adt->action, another_object->
adt->
action);
438 {{
"rotation_euler", std::nullopt, 0}},
445 ASSERT_NE(
nullptr, object->adt);
446 ASSERT_NE(
nullptr, object->adt->action);
447 Action &action =
object->adt->action->wrap();
448 ASSERT_EQ(1, action.
slots().size());
449 ASSERT_EQ(1, action.
layers().size());
456 EXPECT_NE(
nullptr, channelbag->
fcurve_find({
"rotation_euler", 0}));
467 {{
"rotation_euler"}},
474 ASSERT_NE(
nullptr, object->adt);
475 ASSERT_NE(
nullptr, object->adt->action);
476 Action &action =
object->adt->action->wrap();
477 ASSERT_EQ(1, action.
slots().size());
478 ASSERT_EQ(1, action.
layers().size());
485 EXPECT_NE(
nullptr, channelbag->
fcurve_find({
"rotation_euler", 0}));
486 EXPECT_NE(
nullptr, channelbag->
fcurve_find({
"rotation_euler", 1}));
487 EXPECT_NE(
nullptr, channelbag->
fcurve_find({
"rotation_euler", 2}));
496 &armature_object->id, &RNA_PoseBone, pchan);
499 &pose_bone_rna_pointer,
501 {{
"rotation_euler", std::nullopt, 0}},
508 ASSERT_NE(
nullptr, armature_object->adt);
509 ASSERT_NE(
nullptr, armature_object->adt->action);
510 Action &action = armature_object->adt->action->wrap();
511 ASSERT_EQ(1, action.
slots().size());
512 ASSERT_EQ(1, action.
layers().size());
519 EXPECT_NE(
nullptr, channelbag->
fcurve_find({
"pose.bones[\"Bone\"].rotation_euler", 0}));
529 &armature_object_rna_pointer,
531 {{
"pose.bones[\"Bone\"].rotation_euler", std::nullopt, 0}},
538 ASSERT_NE(
nullptr, armature_object->adt);
539 ASSERT_NE(
nullptr, armature_object->adt->action);
540 Action &action = armature_object->adt->action->wrap();
541 ASSERT_EQ(1, action.
slots().size());
542 ASSERT_EQ(1, action.
layers().size());
549 EXPECT_NE(
nullptr, channelbag->
fcurve_find({
"pose.bones[\"Bone\"].rotation_euler", 0}));
561 {
"empty_display_size"},
563 {
"rotation_euler", std::nullopt, 0},
564 {
"rotation_euler", std::nullopt, 2},
572 ASSERT_NE(
nullptr, object->adt);
573 ASSERT_NE(
nullptr, object->adt->action);
574 Action &action =
object->adt->action->wrap();
575 ASSERT_EQ(1, action.
slots().size());
576 ASSERT_EQ(1, action.
layers().size());
583 EXPECT_NE(
nullptr, channelbag->
fcurve_find({
"empty_display_size", 0}));
584 EXPECT_NE(
nullptr, channelbag->
fcurve_find({
"location", 0}));
585 EXPECT_NE(
nullptr, channelbag->
fcurve_find({
"location", 1}));
586 EXPECT_NE(
nullptr, channelbag->
fcurve_find({
"location", 2}));
587 EXPECT_NE(
nullptr, channelbag->
fcurve_find({
"rotation_euler", 0}));
588 EXPECT_NE(
nullptr, channelbag->
fcurve_find({
"rotation_euler", 2}));
600 {{
"empty_display_size"}},
606 ASSERT_NE(
nullptr, object->adt);
607 ASSERT_NE(
nullptr, object->adt->action);
608 Action &action =
object->adt->action->wrap();
611 ASSERT_EQ(1, action.
slots().size());
613 ASSERT_NE(
nullptr, slot_1);
614 EXPECT_STREQ(object->id.name, slot_1->
identifier);
615 EXPECT_STREQ(object->adt->last_slot_identifier, slot_1->
identifier);
619 ASSERT_EQ(1, action.
layers().size());
626 ASSERT_NE(
nullptr, channelbag_1);
635 &armature_object_rna_pointer,
637 {{
"empty_display_size"}},
644 ASSERT_EQ(2, action.
slots().size());
646 ASSERT_NE(
nullptr, slot_2);
647 EXPECT_STREQ(armature_object->id.name, slot_2->
identifier);
648 EXPECT_STREQ(armature_object->adt->last_slot_identifier, slot_2->
identifier);
652 ASSERT_NE(
nullptr, channelbag_2);
668 bAction *action =
object->adt->action;
669 EXPECT_TRUE(action->wrap().is_action_legacy());
670 EXPECT_FALSE(action->wrap().is_action_layered());
686 EXPECT_TRUE(action->wrap().is_action_legacy());
687 EXPECT_FALSE(action->wrap().is_action_layered());
700 {{
"rotation_euler"}},
711 ASSERT_NE(
nullptr, object->adt);
714 ASSERT_EQ(
nullptr, object->adt->action);
722 {
"rotation_euler", std::nullopt, 0},
723 {
"rotation_euler", std::nullopt, 2},
732 Action &action =
object->adt->action->wrap();
733 ASSERT_EQ(1, action.slots().size());
734 ASSERT_EQ(1, action.layers().size());
735 ASSERT_EQ(1, action.layer(0)->strips().size());
736 EXPECT_EQ(object->adt->slot_handle, action.slot(0)->handle);
748 {{
"rotation_euler"}},
756 EXPECT_NE(
nullptr, channelbag->
fcurve_find({
"rotation_euler", 0}));
757 EXPECT_NE(
nullptr, channelbag->
fcurve_find({
"rotation_euler", 2}));
766 object->rot[0] = 42.0;
767 object->rot[1] = 42.0;
768 object->rot[2] = 42.0;
772 {{
"rotation_euler"}},
785 {
"rotation_euler", std::nullopt, 0},
786 {
"rotation_euler", std::nullopt, 2},
793 ASSERT_NE(
nullptr, object->adt);
794 ASSERT_NE(
nullptr, object->adt->action);
795 Action &action =
object->adt->action->wrap();
796 ASSERT_EQ(1, action.
slots().size());
797 ASSERT_EQ(1, action.
layers().size());
803 ASSERT_EQ(2, channelbag->
fcurves().size());
815 object->rot[0] = 86.0;
816 object->rot[1] = 86.0;
817 object->rot[2] = 86.0;
821 {{
"rotation_euler"}},
840 {{
"rotation_euler"}},
864 {{
"rotation_euler"}},
870 ASSERT_NE(
nullptr, object->adt);
871 ASSERT_NE(
nullptr, object->adt->action);
872 Action &action =
object->adt->action->wrap();
873 ASSERT_EQ(1, action.
slots().size());
874 ASSERT_EQ(1, action.
layers().size());
880 ASSERT_EQ(3, channelbag->
fcurves().size());
893 {{
"rotation_euler"}},
906 object->rot[0] = 123.0;
907 object->rot[2] = 123.0;
911 {{
"rotation_euler"}},
935 object->empty_drawsize = 42.0;
936 ensure_legacy_action_assigned(object->id);
940 {{
"empty_display_size"}},
946 ASSERT_NE(
nullptr, object->adt);
947 ASSERT_NE(
nullptr, object->adt->action);
950 ASSERT_NE(
nullptr, fcurve);
951 ASSERT_NE(
nullptr, fcurve->
bezt);
958 object->empty_drawsize = 86.0;
962 {{
"empty_display_size"}},
973 object->empty_drawsize = 7.0;
977 {{
"empty_display_size"}},
998 ensure_legacy_action_assigned(object->id);
1000 &object_rna_pointer,
1002 {{
"rotation_mode"}},
1015 &object_rna_pointer,
1017 {{
"rotation_mode"}},
1035 ensure_legacy_action_assigned(object->id);
1038 &object_rna_pointer,
1040 {{
"location", std::nullopt, 0}, {
"visible_shadow"}},
1049 ASSERT_NE(
nullptr, fcurve_location_x->
grp);
1054 &object->adt->action->curves,
"visible_shadow", 0);
1055 ASSERT_EQ(
nullptr, fcurve_visible_shadow->
grp);
1060 &object_rna_pointer,
1062 {{
"location", std::nullopt, 1}, {
"hide_render"}},
1071 ASSERT_NE(
nullptr, fcurve_location_y->
grp);
1074 ASSERT_NE(
nullptr, fcurve_hide_render->
grp);
1083 ensure_legacy_action_assigned(object->id);
1085 &object_rna_pointer,
1087 {{
"rotation_euler", std::nullopt, 0}},
1094 ASSERT_NE(
nullptr, object->adt);
1095 ASSERT_NE(
nullptr, object->adt->action);
1097 EXPECT_NE(
nullptr,
BKE_fcurve_find(&object->adt->action->curves,
"rotation_euler", 0));
1105 ensure_legacy_action_assigned(object->id);
1107 &object_rna_pointer,
1109 {{
"rotation_euler"}},
1116 ASSERT_NE(
nullptr, object->adt);
1117 ASSERT_NE(
nullptr, object->adt->action);
1119 EXPECT_NE(
nullptr,
BKE_fcurve_find(&object->adt->action->curves,
"rotation_euler", 0));
1120 EXPECT_NE(
nullptr,
BKE_fcurve_find(&object->adt->action->curves,
"rotation_euler", 1));
1121 EXPECT_NE(
nullptr,
BKE_fcurve_find(&object->adt->action->curves,
"rotation_euler", 2));
1130 &armature_object->id, &RNA_PoseBone, pchan);
1132 ensure_legacy_action_assigned(armature_object->id);
1134 &pose_bone_rna_pointer,
1136 {{
"rotation_euler", std::nullopt, 0}},
1143 ASSERT_NE(
nullptr, armature_object->adt);
1144 ASSERT_NE(
nullptr, armature_object->adt->action);
1148 &armature_object->adt->action->curves,
"pose.bones[\"Bone\"].rotation_euler", 0));
1156 ensure_legacy_action_assigned(armature_object->id);
1159 &armature_object_rna_pointer,
1161 {{
"pose.bones[\"Bone\"].rotation_euler", std::nullopt, 0}},
1168 ASSERT_NE(
nullptr, armature_object->adt);
1169 ASSERT_NE(
nullptr, armature_object->adt->action);
1173 &armature_object->adt->action->curves,
"pose.bones[\"Bone\"].rotation_euler", 0));
1181 ensure_legacy_action_assigned(object->id);
1185 &object_rna_pointer,
1188 {
"empty_display_size"},
1190 {
"rotation_euler", std::nullopt, 0},
1191 {
"rotation_euler", std::nullopt, 2},
1199 ASSERT_NE(
nullptr, object->adt);
1200 ASSERT_NE(
nullptr, object->adt->action);
1202 EXPECT_NE(
nullptr,
BKE_fcurve_find(&object->adt->action->curves,
"empty_display_size", 0));
1203 EXPECT_NE(
nullptr,
BKE_fcurve_find(&object->adt->action->curves,
"location", 0));
1204 EXPECT_NE(
nullptr,
BKE_fcurve_find(&object->adt->action->curves,
"location", 1));
1205 EXPECT_NE(
nullptr,
BKE_fcurve_find(&object->adt->action->curves,
"location", 2));
1206 EXPECT_NE(
nullptr,
BKE_fcurve_find(&object->adt->action->curves,
"rotation_euler", 0));
1207 EXPECT_NE(
nullptr,
BKE_fcurve_find(&object->adt->action->curves,
"rotation_euler", 2));
1217 &object_rna_pointer,
1219 {{
"rotation_euler"}},
1230 ASSERT_NE(
nullptr, object->adt);
1233 ASSERT_EQ(
nullptr, object->adt->action);
1237 ensure_legacy_action_assigned(object->id);
1242 &object_rna_pointer,
1245 {
"rotation_euler", std::nullopt, 0},
1246 {
"rotation_euler", std::nullopt, 2},
1256 &object_rna_pointer,
1258 {{
"rotation_euler"}},
1266 EXPECT_NE(
nullptr,
BKE_fcurve_find(&object->adt->action->curves,
"rotation_euler", 0));
1267 EXPECT_NE(
nullptr,
BKE_fcurve_find(&object->adt->action->curves,
"rotation_euler", 2));
1276 object->rot[0] = 42.0;
1277 object->rot[1] = 42.0;
1278 object->rot[2] = 42.0;
1279 ensure_legacy_action_assigned(object->id);
1281 &object_rna_pointer,
1283 {{
"rotation_euler"}},
1293 &object_rna_pointer,
1296 {
"rotation_euler", std::nullopt, 0},
1297 {
"rotation_euler", std::nullopt, 2},
1304 ASSERT_NE(
nullptr, object->adt);
1305 ASSERT_NE(
nullptr, object->adt->action);
1309 ASSERT_NE(
nullptr, fcurve_x);
1310 ASSERT_NE(
nullptr, fcurve_z);
1311 ASSERT_NE(
nullptr, fcurve_x->
bezt);
1312 ASSERT_NE(
nullptr, fcurve_z->
bezt);
1322 object->rot[0] = 86.0;
1323 object->rot[1] = 86.0;
1324 object->rot[2] = 86.0;
1326 &object_rna_pointer,
1328 {{
"rotation_euler"}},
1345 &object_rna_pointer,
1347 {{
"rotation_euler"}},
1368 ensure_legacy_action_assigned(object->id);
1370 &object_rna_pointer,
1372 {{
"rotation_euler"}},
1379 ASSERT_NE(
nullptr, object->adt);
1380 ASSERT_NE(
nullptr, object->adt->action);
1385 ASSERT_NE(
nullptr, fcurve_x);
1386 ASSERT_NE(
nullptr, fcurve_y);
1387 ASSERT_NE(
nullptr, fcurve_z);
1393 &object_rna_pointer,
1395 {{
"rotation_euler"}},
1409 object->rot[0] = 123.0;
1410 object->rot[2] = 123.0;
1412 &object_rna_pointer,
1414 {{
"rotation_euler"}},
1434 &object_with_nla_rna_pointer,
1436 {{
"location", std::nullopt, 0}},
1445 ASSERT_NE(
nullptr, fcurve);
1446 ASSERT_NE(
nullptr, fcurve->
bezt);
1466 &object_with_nla_rna_pointer,
1468 {{
"rotation_quaternion", std::nullopt, 0}},
1489 &object_with_nla_rna_pointer,
1491 {{
"rotation_quaternion", std::nullopt, 0}},
1501 bmain, nla_action,
nullptr, &id_rna_ptr, {
"rotation_quaternion", 0});
1508 &object_with_nla_rna_pointer,
1510 {{
"rotation_quaternion", std::nullopt, 0}},
1529 &object_with_nla_rna_pointer,
1531 {{
"rotation_quaternion", std::nullopt, 0}},
1541 bmain, nla_action,
nullptr, &id_rna_ptr, {
"rotation_quaternion", 0});
1549 &object_with_nla_rna_pointer,
1551 {{
"rotation_quaternion", std::nullopt, 0}},
1564 &object_with_nla_rna_pointer,
1566 {{
"rotation_quaternion", std::nullopt, 0}},
Functions and classes to work with Actions.
Functions to insert, delete or modify keyframes.
Blender kernel action and pose functionality.
bPoseChannel * BKE_pose_channel_find_name(const bPose *pose, const char *name)
AnimData * BKE_animdata_ensure_id(ID *id)
AnimData * BKE_animdata_from_id(const ID *id)
void BKE_pose_ensure(Main *bmain, Object *ob, bArmature *arm, bool do_id_user)
bArmature * BKE_armature_add(Main *bmain, const char *name)
FCurve * BKE_fcurve_find(ListBase *list, const char rna_path[], int array_index)
void * BKE_id_new(Main *bmain, short type, const char *name)
void BKE_main_free(Main *bmain)
General operations, lookup, etc. for materials.
Material * BKE_material_add(Main *bmain, const char *name)
void BKE_object_material_assign(Main *bmain, Object *ob, Material *ma, short act, int assign_type)
Mesh * BKE_mesh_add(Main *bmain, const char *name)
void BKE_mesh_assign_object(Main *bmain, Object *ob, Mesh *mesh)
NlaStrip * BKE_nlastack_add_strip(OwnedAnimData owned_adt, const bool is_liboverride)
NlaTrack * BKE_nlatrack_new_head(ListBase *nla_tracks, bool is_liboverride)
bool BKE_nla_tweakmode_enter(OwnedAnimData owned_adt)
General operations, lookup, etc. for blender objects.
Object * BKE_object_add_only_object(Main *bmain, int type, const char *name) ATTR_RETURNS_NONNULL
EXPECT_EQ(BLI_expr_pylike_eval(expr, nullptr, 0, &result), EXPR_PYLIKE_INVALID)
void BLI_addtail(ListBase *listbase, void *vlink) ATTR_NONNULL(1)
int BLI_listbase_count(const ListBase *listbase) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
char * STRNCPY(char(&dst)[N], const char *src)
#define STRNCPY_UTF8(dst, src)
#define UNUSED_VARS_NDEBUG(...)
#define ID_REFCOUNTING_USERS(id)
Object is a sort of wrapper for general info.
const Layer * layer(int64_t index) const
const Slot * slot(int64_t index) const
blender::Span< const Layer * > layers() const
bool is_action_layered() const
blender::Span< const Slot * > slots() const
Slot * slot_for_handle(slot_handle_t handle)
const FCurve * fcurve_find(const FCurveDescriptor &fcurve_descriptor) const
blender::Span< const FCurve * > fcurves() const
int get_count(const SingleKeyingResult result) const
blender::Span< const Strip * > strips() const
const Strip * strip(int64_t index) const
const Channelbag * channelbag_for_slot(const Slot &slot) const
blender::Span< const Channelbag * > channelbags() const
const Channelbag * channelbag(int64_t index) const
const T & data(const Action &owning_action) const
PointerRNA material_rna_pointer
PointerRNA object_rna_pointer
void ensure_legacy_action_assigned(ID &id)
static void TearDownTestSuite()
static void SetUpTestSuite()
PointerRNA object_with_nla_rna_pointer
PointerRNA armature_object_rna_pointer
PointerRNA cube_rna_pointer
void ensure_action_is_legacy(bAction &action)
PointerRNA cube_mesh_rna_pointer
void * MEM_callocN(size_t len, const char *str)
TEST_F(ActionIteratorsTest, iterate_all_fcurves_of_slot)
Action & action_add(Main &bmain, StringRefNull name)
FCurve * action_fcurve_ensure_legacy(Main *bmain, bAction *act, const char group[], PointerRNA *ptr, const FCurveDescriptor &fcurve_descriptor)
CombinedKeyingResult insert_keyframes(Main *bmain, PointerRNA *struct_pointer, std::optional< StringRefNull > channel_group, const blender::Span< RNAPath > rna_paths, std::optional< float > scene_frame, const AnimationEvalContext &anim_eval_context, eBezTriple_KeyframeType key_type, eInsertKeyFlags insert_key_flags)
Main key-frame insertion API.
SingleKeyingResult insert_vert_fcurve(FCurve *fcu, const float2 position, const KeyframeSettings &settings, eInsertKeyFlags flag)
Main Key-framing API call.
bool assign_action(bAction *action, ID &animated_id)
ActionSlotAssignmentResult assign_action_slot(Slot *slot_to_assign, ID &animated_id)
PointerRNA RNA_pointer_create_discrete(ID *id, StructRNA *type, void *data)
PointerRNA RNA_id_pointer_create(ID *id)