27#include "testing/testing.h"
69 Layer &layer = action->layer_add(
"layer name");
75 <<
"Expected newly added layer to become the active layer.";
76 ASSERT_EQ(0, layer.
strips().size()) <<
"Expected newly added layer to have no strip.";
84 action->idroot =
ID_CA;
85 ASSERT_NE(0, action->idroot) <<
"action->idroot should not be zero at the start of this test.";
87 action->layer_add(
"layer name");
90 <<
"action->idroot should get reset when the Action becomes layered.";
95 Layer &layer0 = action->layer_add(
"Test Læür nul");
96 Layer &layer1 = action->layer_add(
"Test Læür één");
97 Layer &layer2 = action->layer_add(
"Test Læür twee");
101 layer0.
strip_add(*action, Strip::Type::Keyframe);
102 layer1.
strip_add(*action, Strip::Type::Keyframe);
103 layer2.
strip_add(*action, Strip::Type::Keyframe);
108 EXPECT_FALSE(action->layer_remove(other_layer))
109 <<
"Removing a layer not owned by the Action should be gracefully rejected";
113 EXPECT_TRUE(action->layer_remove(layer1));
115 EXPECT_STREQ(layer0.
name, action->layer(0)->name);
116 EXPECT_STREQ(layer2.
name, action->layer(1)->name);
118 EXPECT_TRUE(action->layer_remove(layer2));
120 EXPECT_STREQ(layer0.
name, action->layer(0)->name);
122 EXPECT_TRUE(action->layer_remove(layer0));
128 Layer &layer = action->layer_add(
"Test Læür");
131 ASSERT_EQ(1, layer.
strips().size());
134 constexpr float inf = std::numeric_limits<float>::infinity();
139 Strip &another_strip = layer.
strip_add(*action, Strip::Type::Keyframe);
140 ASSERT_EQ(2, layer.
strips().size());
149 Slot &slot = action->slot_add();
151 bmain, slot, {
"location", 0}, {1.0f, 47.0f}, settings);
153 bmain, slot, {
"location", 0}, {1.0f, 47.0f}, settings);
158 Layer &layer = action->layer_add(
"Test Læür");
170 Slot &slot = action->slot_add();
171 strip_data0.
keyframe_insert(bmain, slot, {
"location", 0}, {1.0f, 47.0f}, settings);
172 strip_data1.
keyframe_insert(bmain, slot, {
"location", 0}, {1.0f, 48.0f}, settings);
173 strip_data2.
keyframe_insert(bmain, slot, {
"location", 0}, {1.0f, 49.0f}, settings);
174 strip_data3.
keyframe_insert(bmain, slot, {
"location", 0}, {1.0f, 50.0f}, settings);
176 EXPECT_EQ(4, action->strip_keyframe_data().size());
183 EXPECT_EQ(3, action->strip_keyframe_data().size());
196 EXPECT_EQ(2, action->strip_keyframe_data().size());
206 EXPECT_EQ(1, action->strip_keyframe_data().size());
213 EXPECT_EQ(0, action->strip_keyframe_data().size());
217 Layer &other_layer = action->layer_add(
"Another Layer");
218 Strip &other_strip = other_layer.
strip_add(*action, Strip::Type::Keyframe);
221 <<
"Removing a strip not owned by the layer should be gracefully rejected";
231 Layer &layer = action->layer_add(
"Test Læür");
244 Slot &slot = action->slot_add();
245 strip_data_0_1.
keyframe_insert(bmain, slot, {
"location", 0}, {1.0f, 47.0f}, settings);
246 strip_data_2.
keyframe_insert(bmain, slot, {
"location", 0}, {1.0f, 48.0f}, settings);
248 EXPECT_EQ(3, action->strip_keyframe_data().size());
256 EXPECT_EQ(3, action->strip_keyframe_data().size());
267 EXPECT_EQ(2, action->strip_keyframe_data().size());
277 Slot &slot = action->slot_add();
281 EXPECT_STREQ(
"XXSlot", slot.
name);
286 Slot &slot = action->slot_add_for_id(cube->id);
290 EXPECT_STREQ(cube->id.name, slot.
name);
300 action->idroot =
ID_CA;
301 ASSERT_NE(0, action->idroot) <<
"action->idroot should not be zero at the start of this test.";
306 <<
"action->idroot should get reset when the Action becomes layered.";
311 Slot &slot_cube = action->slot_add();
312 Slot &slot_suzanne = action->slot_add();
326 Slot &slot = action->slot_add();
330 EXPECT_TRUE(action->slot_remove(slot));
332 <<
"Removing a slot should not change the last-used slot handle.";
338 EXPECT_FALSE(action->slot_remove(slot));
342 Slot &slot = action->slot_add();
348 action->layer_keystrip_ensure();
354 EXPECT_TRUE(action->slot_remove(slot));
356 <<
"Removing a slot should not change the last-used slot handle.";
365 Slot &slot1 = action->slot_add();
366 Slot &slot2 = action->slot_add();
367 Slot &slot3 = action->slot_add();
377 action->layer_keystrip_ensure();
384 EXPECT_TRUE(action->slot_remove(slot2));
389 EXPECT_EQ(action->slot_for_handle(slot2_handle),
nullptr);
399 Slot &slot = action->slot_add_for_id(cube->id);
403 ASSERT_EQ(cube->adt->slot_handle, slot.
handle);
406 ASSERT_TRUE(action->slot_remove(slot));
407 EXPECT_EQ(cube->adt->slot_handle, removed_slot_handle);
411 action->last_slot_handle = 3;
412 Slot &slot1 = action->slot_add();
413 ASSERT_EQ(4, slot1.
handle);
414 ASSERT_EQ(4, action->last_slot_handle);
415 ASSERT_TRUE(action->slot_remove(slot1));
417 Slot &slot2 = action->slot_add();
426 Slot &slot_cube = action->slot_add();
427 ASSERT_NE(
nullptr, slot_cube.
runtime);
428 ASSERT_STREQ(slot_cube.
name,
"XXSlot");
432 EXPECT_STREQ(slot_cube.
name,
"OBSlot");
433 EXPECT_STREQ(slot_cube.
name, cube->adt->slot_name)
434 <<
"The slot name should be copied to the adt";
437 <<
"Expecting Cube to be registered as animated by its slot.";
442 EXPECT_STREQ(slot_cube.
name,
"OBSlot");
443 EXPECT_STREQ(slot_cube.
name, cube->adt->slot_name)
444 <<
"The slot name should be copied to the adt";
447 <<
"Expecting Suzanne to be registered as animated by the Cube slot.";
455 <<
"Expecting Cube to no longer be registered as user of its old slot.";
457 <<
"Expecting Cube to be registered as user of its new slot.";
463 const int user_count_pre = action->id.us;
464 Slot &slot_cube_2 = action->slot_add();
467 ASSERT_EQ(action->id.us, user_count_pre)
468 <<
"Assigning to a different slot of the same Action should _not_ change the user "
469 "count of that Action";
471 <<
"Expecting Cube to no longer be registered as animated by the Cube slot.";
473 <<
"Expecting Cube to be registered as animated by the 'cube_2' slot.";
477 const int user_count_pre = action->id.us;
479 ASSERT_EQ(action->id.us, user_count_pre - 1)
480 <<
"Unassigning an Action should lower its user count";
482 ASSERT_EQ(2, action->slots().size()) <<
"Expecting the Action to have two Slots";
483 EXPECT_FALSE(action->slot(0)->users(*bmain).contains(&cube->id))
484 <<
"Expecting Cube to no longer be registered as animated by any slot.";
485 EXPECT_FALSE(action->slot(1)->users(*bmain).contains(&cube->id))
486 <<
"Expecting Cube to no longer be registered as animated by any slot.";
491 Slot &another_slot_cube = action->slot_add();
495 EXPECT_STREQ(
"OBSlot.002", another_slot_cube.
name) <<
"The slot should be uniquely named";
496 EXPECT_STREQ(
"OBSlot.002", cube->adt->slot_name) <<
"The slot name should be copied to the adt";
497 EXPECT_TRUE(another_slot_cube.
users(*bmain).
contains(&cube->id))
498 <<
"Expecting Cube to be registered as animated by the 'another_slot_cube' slot.";
504 <<
"Mesh should not be animatable by an Object slot";
506 <<
"Expecting Mesh to not be registered as animated by the 'slot_cube' slot.";
512 Slot &slot_cube = action->slot_add();
515 EXPECT_STREQ(
"OBSlot", slot_cube.
name);
516 EXPECT_STREQ(slot_cube.
name, cube->adt->slot_name)
517 <<
"The slot name should be copied to the adt";
519 action->slot_name_define(slot_cube,
"New Slot Name");
520 EXPECT_STREQ(
"New Slot Name", slot_cube.
name);
526 action->slot_name_propagate(*bmain, slot_cube);
527 EXPECT_STREQ(
"New Slot Name", cube->adt->slot_name);
532 action->slot_name_define(slot_cube,
"Even Newer Name");
534 EXPECT_STREQ(
"Even Newer Name", cube->adt->slot_name);
539 class AccessibleSlot :
public Slot {
541 void name_ensure_prefix()
547 Slot &raw_slot = action->slot_add();
548 AccessibleSlot &slot =
static_cast<AccessibleSlot &
>(raw_slot);
549 ASSERT_STREQ(
"XXSlot", slot.name);
550 ASSERT_EQ(0, slot.idtype);
553 slot.name_ensure_prefix();
554 EXPECT_STREQ(
"XXSlot", slot.name);
558 slot.name_ensure_prefix();
559 EXPECT_STREQ(
"CASlot", slot.name);
562 action->slot_name_define(slot,
"CANewName");
564 slot.name_ensure_prefix();
565 EXPECT_STREQ(
"MENewName", slot.name);
569 slot.name_ensure_prefix();
570 EXPECT_STREQ(
"XXNewName", slot.name);
575 Slot &slot = action->slot_add();
584 Slot &slot1 = action->slot_add();
585 Slot &slot2 = action->slot_add();
587 action->slot_name_define(slot1,
"New Slot Name");
588 action->slot_name_define(slot2,
"New Slot Name");
589 EXPECT_STREQ(
"New Slot Name", slot1.
name);
590 EXPECT_STREQ(
"New Slot Name.001", slot2.
name);
597 EXPECT_EQ(
nullptr, action->find_suitable_slot_for(cube->id));
602 Slot &slot = action->slot_add();
606 EXPECT_EQ(&slot, action->find_suitable_slot_for(cube->id));
615 Slot &other_slot = action->slot_add();
623 EXPECT_EQ(&slot, action->find_suitable_slot_for(cube->id));
631 EXPECT_EQ(&other_slot, action->find_suitable_slot_for(cube->id));
638 EXPECT_EQ(&slot, action->find_suitable_slot_for(cube->id));
644 EXPECT_EQ(
nullptr, action->slot_active_get());
647 EXPECT_EQ(
nullptr, action->slot_active_get());
652 EXPECT_EQ(
nullptr, action->slot_active_get())
653 <<
"Adding the first slot should not change what is the active slot.";
655 action->slot_active_set(slot_cube.
handle);
656 EXPECT_EQ(&slot_cube, action->slot_active_get())
657 <<
"It should be possible to activate the only available slot";
661 EXPECT_EQ(
nullptr, action->slot_active_get())
662 <<
"It should be possible to de-activate the only available slot";
668 Slot &slot_cube = *action->slot(0);
669 action->slot_active_set(slot_cube.
handle);
673 EXPECT_EQ(&slot_cube, action->slot_active_get())
674 <<
"Adding a subsequent slot should not change what is the active slot.";
677 action->slot_active_set(slot_suz.
handle);
678 EXPECT_EQ(&slot_suz, action->slot_active_get());
683 action->slot_active_set(slot_bob.
handle);
684 EXPECT_EQ(&slot_bob, action->slot_active_get());
690 EXPECT_EQ(
nullptr, action->slot_active_get());
699 constexpr float inf = std::numeric_limits<float>::infinity();
700 Layer &layer0 = action->layer_add(
"Test Læür nul");
711 <<
"Strip should not contain frames before its first frame";
712 EXPECT_TRUE(strip.
contains_frame(1.0f)) <<
"Strip should contain its first frame.";
713 EXPECT_TRUE(strip.
contains_frame(2.0f)) <<
"Strip should contain its last frame.";
715 <<
"Strip should not contain frames after its last frame";
724 strip.
resize(1.0f, 172800.0f);
725 EXPECT_TRUE(strip.
contains_frame(172800.0f)) <<
"Strip should contain its last frame.";
727 <<
"Strip should not contain frames after its last frame";
737 Slot &slot = action->slot_add();
739 Layer &layer = action->layer_add(
"Kübus layer");
746 bmain, slot, {
"location", 0}, {1.0f, 47.0f}, settings);
748 <<
"Expected keyframe insertion to be successful";
757 bmain, slot, {
"location", 0}, {5.0f, 47.1f}, settings);
759 ASSERT_EQ(1,
channels->fcurves().size()) <<
"Expect insertion with the same (slot/rna "
760 "path/array index) tuple to go into the same FCurve";
762 <<
"Expect insertion with the same (slot/rna path/array index) tuple to go into the same "
770 bmain, slot, {
"rotation_quaternion", 0}, {1.0f, 0.25f}, settings);
772 ASSERT_EQ(2,
channels->fcurves().size()) <<
"Expected a second FCurve to be created.";
780 <<
"nullptr Actions should be assignable to any type.";
782 <<
"nullptr Actions should be assignable to any type.";
785 <<
"Empty Actions should be assignable to any type.";
787 <<
"Empty Actions should be assignable to any type.";
792 ASSERT_FALSE(action->is_empty());
793 ASSERT_TRUE(action->is_action_legacy());
794 ASSERT_EQ(0, action->idroot);
797 <<
"Legacy Actions with idroot=0 should be assignable to any type.";
799 <<
"Legacy Actions with idroot=0 should be assignable to any type.";
802 action->idroot =
ID_CA;
804 <<
"Legacy Actions with idroot=ID_CA should NOT be assignable to ID_OB.";
806 <<
"Legacy Actions with idroot=CA should be assignable to ID_CA.";
810 action->layer_add(
"layer");
811 ASSERT_EQ(0, action->idroot) <<
"Adding a layer should clear the idroot.";
814 <<
"Layered Actions should be assignable to any type.";
816 <<
"Layered Actions should be assignable to any type.";
824 EXPECT_TRUE(action->is_empty());
836 EXPECT_FALSE(fcurve ==
nullptr);
841 EXPECT_TRUE(action->is_action_legacy());
852 Slot &slot = action->slot_add();
855 EXPECT_TRUE(action->is_action_layered());
879 EXPECT_TRUE(action->is_empty());
892 ASSERT_TRUE(converted != action);
893 EXPECT_STREQ(converted->
id.
name,
"ACACÄnimåtië_layered");
906 ASSERT_STREQ(group->
name,
"Test");
912 bmain,
ID_AC,
"name_for_an_action_that_is_exactly_64_chars_which_is_MAX_ID_NAME"));
917 EXPECT_STREQ(converted->
id.
name,
918 "ACname_for_an_action_that_is_exactly_64_chars_which_is_MA_layered");
923 EXPECT_TRUE(action->is_empty());
931 ASSERT_NE(rename_group,
nullptr);
932 ASSERT_STREQ(rename_group->name,
"Test_Rename");
934 strcpy(rename_group->name,
"Test");
945 EXPECT_STREQ(test_group->
name,
"Test");
949 EXPECT_STREQ(test_two_group->
name,
"Test_Two");
954 EXPECT_STREQ(test_three_group->
name,
"Test_Three");
959 EXPECT_STREQ(test_rename_group->
name,
"Test.001");
963 ASSERT_NE(converted, action);
968 ASSERT_TRUE(action->is_empty());
970 ASSERT_TRUE(converted != action);
978 U.experimental.use_animation_baklava = 1;
981 EXPECT_TRUE(action->is_empty());
983 Slot &slot_cube = action->slot_add();
998 ASSERT_EQ(action->layer_array_num, 1);
1001 Layer *layer_1 = action->layer(0);
1019 move_slot(*bmain, slot_suzanne, *action_2, *action);
1024 ASSERT_EQ(action->slot_array_num, 2);
1028 ASSERT_EQ(action, cube->adt->action);
1029 ASSERT_EQ(action, suzanne->adt->action);
1037 fcu.
bezt = MEM_cnew_array<BezTriple>(num_keyframes, __func__);
1045 memset(&the_keyframe, 0,
sizeof(the_keyframe));
1048 the_keyframe.
vec[0][0] =
x - 1.0f;
1049 the_keyframe.
vec[0][1] =
y;
1050 the_keyframe.
vec[1][0] =
x;
1051 the_keyframe.
vec[1][1] =
y;
1052 the_keyframe.
vec[2][0] =
x + 1.0f;
1053 the_keyframe.
vec[2][1] =
y;
1055 memcpy(&fcu.
bezt[fcu.
totvert], &the_keyframe,
sizeof(the_keyframe));
1061#ifdef WITH_ANIM_BAKLAVA
1110 const Action &empty = action_new();
1116 FCurve &fcu = *MEM_cnew<FCurve>(__func__);
1120 Action &action = action_new();
1124 EXPECT_FLOAT_EQ(frame_range[0], 1.0f);
1125 EXPECT_FLOAT_EQ(frame_range[1], 1.0f);
1130 FCurve &fcu1 = *MEM_cnew<FCurve>(__func__);
1131 FCurve &fcu2 = *MEM_cnew<FCurve>(__func__);
1137 Action &action = action_new();
1142 EXPECT_FLOAT_EQ(frame_range[0], 1.0f);
1143 EXPECT_FLOAT_EQ(frame_range[1], 1.5f);
1148 FCurve &fcu = *MEM_cnew<FCurve>(__func__);
1153 Action &action = action_new();
1157 EXPECT_FLOAT_EQ(frame_range[0], 1.0f);
1158 EXPECT_FLOAT_EQ(frame_range[1], 1.5f);
1187 FCurve &fcu0 = channel_bag->fcurve_ensure(
nullptr, {
"fcu0", 0, std::nullopt,
"group0"});
1188 FCurve &fcu1 = channel_bag->fcurve_ensure(
nullptr, {
"fcu1", 0, std::nullopt,
"group0"});
1189 FCurve &fcu2 = channel_bag->fcurve_ensure(
nullptr, {
"fcu2", 0, std::nullopt,
"group1"});
1190 FCurve &fcu3 = channel_bag->fcurve_ensure(
nullptr, {
"fcu3", 0, std::nullopt,
"group1"});
1191 FCurve &fcu4 = channel_bag->fcurve_ensure(
nullptr, {
"fcu4", 0, std::nullopt, std::nullopt});
1193 ASSERT_EQ(5, channel_bag->fcurves().size());
1194 ASSERT_EQ(2, channel_bag->channel_groups().size());
1200 channel_bag->fcurve_move(fcu0, 0);
1201 EXPECT_EQ(&fcu0, channel_bag->fcurve(0));
1202 EXPECT_EQ(&fcu1, channel_bag->fcurve(1));
1203 EXPECT_EQ(&fcu2, channel_bag->fcurve(2));
1204 EXPECT_EQ(&fcu3, channel_bag->fcurve(3));
1205 EXPECT_EQ(&fcu4, channel_bag->fcurve(4));
1213 channel_bag->fcurve_move(fcu4, 0);
1218 EXPECT_EQ(&fcu4, channel_bag->fcurve(0));
1219 EXPECT_EQ(&fcu0, channel_bag->fcurve(1));
1220 EXPECT_EQ(&fcu1, channel_bag->fcurve(2));
1221 EXPECT_EQ(&fcu2, channel_bag->fcurve(3));
1222 EXPECT_EQ(&fcu3, channel_bag->fcurve(4));
1230 channel_bag->fcurve_move(fcu1, 4);
1235 EXPECT_EQ(&fcu4, channel_bag->fcurve(0));
1236 EXPECT_EQ(&fcu0, channel_bag->fcurve(1));
1237 EXPECT_EQ(&fcu2, channel_bag->fcurve(2));
1238 EXPECT_EQ(&fcu3, channel_bag->fcurve(3));
1239 EXPECT_EQ(&fcu1, channel_bag->fcurve(4));
1247 channel_bag->fcurve_move(fcu4, 2);
1252 EXPECT_EQ(&fcu0, channel_bag->fcurve(0));
1253 EXPECT_EQ(&fcu2, channel_bag->fcurve(1));
1254 EXPECT_EQ(&fcu4, channel_bag->fcurve(2));
1255 EXPECT_EQ(&fcu3, channel_bag->fcurve(3));
1256 EXPECT_EQ(&fcu1, channel_bag->fcurve(4));
1266 ASSERT_TRUE(channel_bag->channel_groups().is_empty());
1268 bActionGroup &group0 = channel_bag->channel_group_create(
"Foo");
1269 ASSERT_EQ(channel_bag->channel_groups().size(), 1);
1273 EXPECT_EQ(&group0, channel_bag->channel_group(0));
1278 bActionGroup &group1 = channel_bag->channel_group_create(
"Bar");
1279 ASSERT_EQ(channel_bag->channel_groups().size(), 2);
1283 EXPECT_EQ(&group0, channel_bag->channel_group(0));
1284 EXPECT_EQ(&group1, channel_bag->channel_group(1));
1289 bActionGroup &group2 = channel_bag->channel_group_create(
"Yar");
1290 ASSERT_EQ(channel_bag->channel_groups().size(), 3);
1294 EXPECT_EQ(&group0, channel_bag->channel_group(0));
1295 EXPECT_EQ(&group1, channel_bag->channel_group(1));
1296 EXPECT_EQ(&group2, channel_bag->channel_group(2));
1301 bActionGroup &group0 = channel_bag->channel_group_create(
"Group0");
1302 bActionGroup &group1 = channel_bag->channel_group_create(
"Group1");
1303 bActionGroup &group2 = channel_bag->channel_group_create(
"Group2");
1305 FCurve &fcu0 = channel_bag->fcurve_ensure(
nullptr, {
"fcu0", 0, std::nullopt,
"Group0"});
1306 FCurve &fcu1 = channel_bag->fcurve_ensure(
nullptr, {
"fcu1", 0, std::nullopt,
"Group0"});
1307 FCurve &fcu2 = channel_bag->fcurve_ensure(
nullptr, {
"fcu2", 0, std::nullopt,
"Group2"});
1308 FCurve &fcu3 = channel_bag->fcurve_ensure(
nullptr, {
"fcu3", 0, std::nullopt,
"Group2"});
1309 FCurve &fcu4 = channel_bag->fcurve_ensure(
nullptr, {
"fcu4", 0, std::nullopt, std::nullopt});
1311 ASSERT_EQ(3, channel_bag->channel_groups().size());
1312 ASSERT_EQ(5, channel_bag->fcurves().size());
1317 EXPECT_EQ(
false, channel_bag->channel_group_remove(bogus));
1318 ASSERT_EQ(3, channel_bag->channel_groups().size());
1319 ASSERT_EQ(5, channel_bag->fcurves().size());
1320 EXPECT_EQ(&group0, channel_bag->channel_group(0));
1321 EXPECT_EQ(&group1, channel_bag->channel_group(1));
1322 EXPECT_EQ(&group2, channel_bag->channel_group(2));
1323 EXPECT_EQ(&fcu0, channel_bag->fcurve(0));
1324 EXPECT_EQ(&fcu1, channel_bag->fcurve(1));
1325 EXPECT_EQ(&fcu2, channel_bag->fcurve(2));
1326 EXPECT_EQ(&fcu3, channel_bag->fcurve(3));
1327 EXPECT_EQ(&fcu4, channel_bag->fcurve(4));
1335 EXPECT_EQ(
true, channel_bag->channel_group_remove(group1));
1336 ASSERT_EQ(2, channel_bag->channel_groups().size());
1337 ASSERT_EQ(5, channel_bag->fcurves().size());
1338 EXPECT_EQ(&group0, channel_bag->channel_group(0));
1339 EXPECT_EQ(&group2, channel_bag->channel_group(1));
1340 EXPECT_EQ(&fcu0, channel_bag->fcurve(0));
1341 EXPECT_EQ(&fcu1, channel_bag->fcurve(1));
1342 EXPECT_EQ(&fcu2, channel_bag->fcurve(2));
1343 EXPECT_EQ(&fcu3, channel_bag->fcurve(3));
1344 EXPECT_EQ(&fcu4, channel_bag->fcurve(4));
1353 EXPECT_EQ(
true, channel_bag->channel_group_remove(group0));
1354 ASSERT_EQ(1, channel_bag->channel_groups().size());
1355 ASSERT_EQ(5, channel_bag->fcurves().size());
1356 EXPECT_EQ(&group2, channel_bag->channel_group(0));
1357 EXPECT_EQ(&fcu2, channel_bag->fcurve(0));
1358 EXPECT_EQ(&fcu3, channel_bag->fcurve(1));
1359 EXPECT_EQ(&fcu0, channel_bag->fcurve(2));
1360 EXPECT_EQ(&fcu1, channel_bag->fcurve(3));
1361 EXPECT_EQ(&fcu4, channel_bag->fcurve(4));
1370 EXPECT_EQ(
true, channel_bag->channel_group_remove(group2));
1371 ASSERT_EQ(0, channel_bag->channel_groups().size());
1372 ASSERT_EQ(5, channel_bag->fcurves().size());
1373 EXPECT_EQ(&fcu2, channel_bag->fcurve(0));
1374 EXPECT_EQ(&fcu3, channel_bag->fcurve(1));
1375 EXPECT_EQ(&fcu0, channel_bag->fcurve(2));
1376 EXPECT_EQ(&fcu1, channel_bag->fcurve(3));
1377 EXPECT_EQ(&fcu4, channel_bag->fcurve(4));
1387 bActionGroup &group0a = channel_bag->channel_group_create(
"Foo");
1388 bActionGroup &group1a = channel_bag->channel_group_create(
"Bar");
1389 bActionGroup &group2a = channel_bag->channel_group_create(
"Yar");
1391 bActionGroup *group0b = channel_bag->channel_group_find(
"Foo");
1392 bActionGroup *group1b = channel_bag->channel_group_find(
"Bar");
1393 bActionGroup *group2b = channel_bag->channel_group_find(
"Yar");
1399 EXPECT_EQ(
nullptr, channel_bag->channel_group_find(
"Wat"));
1404 bActionGroup &group0 = channel_bag->channel_group_create(
"Foo");
1405 bActionGroup &group1 = channel_bag->channel_group_create(
"Bar");
1406 EXPECT_EQ(channel_bag->channel_groups().size(), 2);
1408 EXPECT_EQ(&group0, &channel_bag->channel_group_ensure(
"Foo"));
1409 EXPECT_EQ(channel_bag->channel_groups().size(), 2);
1411 EXPECT_EQ(&group1, &channel_bag->channel_group_ensure(
"Bar"));
1412 EXPECT_EQ(channel_bag->channel_groups().size(), 2);
1414 bActionGroup &group2 = channel_bag->channel_group_ensure(
"Yar");
1415 ASSERT_EQ(channel_bag->channel_groups().size(), 3);
1416 EXPECT_EQ(&group2, channel_bag->channel_group(2));
1421 FCurve &fcu0 = channel_bag->fcurve_ensure(
nullptr, {
"fcu0", 0, std::nullopt, std::nullopt});
1422 EXPECT_EQ(1, channel_bag->fcurves().size());
1423 EXPECT_TRUE(channel_bag->channel_groups().is_empty());
1428 channel_bag->fcurve_ensure(
nullptr, {
"fcu0", 0, std::nullopt,
"group0"});
1429 EXPECT_EQ(1, channel_bag->fcurves().size());
1431 EXPECT_TRUE(channel_bag->channel_groups().is_empty());
1436 FCurve &fcu1 = channel_bag->fcurve_ensure(
nullptr, {
"fcu1", 0, std::nullopt,
"group0"});
1437 ASSERT_EQ(2, channel_bag->fcurves().size());
1438 ASSERT_EQ(1, channel_bag->channel_groups().size());
1440 EXPECT_EQ(&fcu1, channel_bag->fcurve(0));
1441 EXPECT_EQ(&fcu0, channel_bag->fcurve(1));
1451 FCurve &fcu2 = channel_bag->fcurve_ensure(
nullptr, {
"fcu2", 0, std::nullopt,
"group1"});
1452 ASSERT_EQ(3, channel_bag->fcurves().size());
1453 ASSERT_EQ(2, channel_bag->channel_groups().size());
1454 EXPECT_EQ(&group0, channel_bag->channel_group(0));
1456 EXPECT_EQ(&fcu1, channel_bag->fcurve(0));
1457 EXPECT_EQ(&fcu2, channel_bag->fcurve(1));
1458 EXPECT_EQ(&fcu0, channel_bag->fcurve(2));
1469 FCurve &fcu3 = channel_bag->fcurve_ensure(
nullptr, {
"fcu3", 0, std::nullopt,
"group0"});
1470 ASSERT_EQ(4, channel_bag->fcurves().size());
1471 ASSERT_EQ(2, channel_bag->channel_groups().size());
1472 EXPECT_EQ(&group0, channel_bag->channel_group(0));
1473 EXPECT_EQ(&group1, channel_bag->channel_group(1));
1474 EXPECT_EQ(&fcu1, channel_bag->fcurve(0));
1475 EXPECT_EQ(&fcu3, channel_bag->fcurve(1));
1476 EXPECT_EQ(&fcu2, channel_bag->fcurve(2));
1477 EXPECT_EQ(&fcu0, channel_bag->fcurve(3));
1489 FCurve &fcu4 = channel_bag->fcurve_ensure(
nullptr, {
"fcu4", 0, std::nullopt,
"group1"});
1490 ASSERT_EQ(5, channel_bag->fcurves().size());
1491 ASSERT_EQ(2, channel_bag->channel_groups().size());
1492 EXPECT_EQ(&group0, channel_bag->channel_group(0));
1493 EXPECT_EQ(&group1, channel_bag->channel_group(1));
1494 EXPECT_EQ(&fcu1, channel_bag->fcurve(0));
1495 EXPECT_EQ(&fcu3, channel_bag->fcurve(1));
1496 EXPECT_EQ(&fcu2, channel_bag->fcurve(2));
1497 EXPECT_EQ(&fcu4, channel_bag->fcurve(3));
1498 EXPECT_EQ(&fcu0, channel_bag->fcurve(4));
1512 FCurve &fcu0 = channel_bag->fcurve_ensure(
nullptr, {
"fcu0", 0, std::nullopt,
"group0"});
1513 FCurve &fcu1 = channel_bag->fcurve_ensure(
nullptr, {
"fcu1", 0, std::nullopt,
"group0"});
1514 FCurve &fcu2 = channel_bag->fcurve_ensure(
nullptr, {
"fcu2", 0, std::nullopt,
"group1"});
1515 FCurve &fcu3 = channel_bag->fcurve_ensure(
nullptr, {
"fcu3", 0, std::nullopt,
"group1"});
1516 FCurve &fcu4 = channel_bag->fcurve_ensure(
nullptr, {
"fcu4", 0, std::nullopt, std::nullopt});
1518 ASSERT_EQ(5, channel_bag->fcurves().size());
1519 ASSERT_EQ(2, channel_bag->channel_groups().size());
1534 channel_bag->fcurve_remove(fcu3);
1535 ASSERT_EQ(4, channel_bag->fcurves().size());
1536 ASSERT_EQ(2, channel_bag->channel_groups().size());
1537 EXPECT_EQ(&group0, channel_bag->channel_group(0));
1538 EXPECT_EQ(&group1, channel_bag->channel_group(1));
1548 channel_bag->fcurve_remove(fcu0);
1549 ASSERT_EQ(3, channel_bag->fcurves().size());
1550 ASSERT_EQ(2, channel_bag->channel_groups().size());
1551 EXPECT_EQ(&group0, channel_bag->channel_group(0));
1552 EXPECT_EQ(&group1, channel_bag->channel_group(1));
1561 channel_bag->fcurve_remove(fcu1);
1562 ASSERT_EQ(2, channel_bag->fcurves().size());
1563 ASSERT_EQ(1, channel_bag->channel_groups().size());
1564 EXPECT_EQ(&group1, channel_bag->channel_group(0));
1570 channel_bag->fcurve_remove(fcu4);
1571 ASSERT_EQ(1, channel_bag->fcurves().size());
1572 ASSERT_EQ(1, channel_bag->channel_groups().size());
1573 EXPECT_EQ(&group1, channel_bag->channel_group(0));
1578 channel_bag->fcurve_remove(fcu2);
1579 ASSERT_EQ(0, channel_bag->fcurves().size());
1580 ASSERT_EQ(0, channel_bag->channel_groups().size());
1585 FCurve &fcu0 = channel_bag->fcurve_ensure(
nullptr, {
"fcu0", 0, std::nullopt,
"group0"});
1586 FCurve &fcu1 = channel_bag->fcurve_ensure(
nullptr, {
"fcu1", 0, std::nullopt,
"group1"});
1587 FCurve &fcu2 = channel_bag->fcurve_ensure(
nullptr, {
"fcu2", 0, std::nullopt,
"group1"});
1588 FCurve &fcu3 = channel_bag->fcurve_ensure(
nullptr, {
"fcu3", 0, std::nullopt,
"group2"});
1589 FCurve &fcu4 = channel_bag->fcurve_ensure(
nullptr, {
"fcu4", 0, std::nullopt, std::nullopt});
1591 ASSERT_EQ(5, channel_bag->fcurves().size());
1592 ASSERT_EQ(3, channel_bag->channel_groups().size());
1598 channel_bag->channel_group_move(group0, 2);
1599 EXPECT_EQ(&group1, channel_bag->channel_group(0));
1600 EXPECT_EQ(&group2, channel_bag->channel_group(1));
1601 EXPECT_EQ(&group0, channel_bag->channel_group(2));
1608 EXPECT_EQ(&fcu1, channel_bag->fcurve(0));
1609 EXPECT_EQ(&fcu2, channel_bag->fcurve(1));
1610 EXPECT_EQ(&fcu3, channel_bag->fcurve(2));
1611 EXPECT_EQ(&fcu0, channel_bag->fcurve(3));
1612 EXPECT_EQ(&fcu4, channel_bag->fcurve(4));
1619 channel_bag->channel_group_move(group1, 1);
1620 EXPECT_EQ(&group2, channel_bag->channel_group(0));
1621 EXPECT_EQ(&group1, channel_bag->channel_group(1));
1622 EXPECT_EQ(&group0, channel_bag->channel_group(2));
1629 EXPECT_EQ(&fcu3, channel_bag->fcurve(0));
1630 EXPECT_EQ(&fcu1, channel_bag->fcurve(1));
1631 EXPECT_EQ(&fcu2, channel_bag->fcurve(2));
1632 EXPECT_EQ(&fcu0, channel_bag->fcurve(3));
1633 EXPECT_EQ(&fcu4, channel_bag->fcurve(4));
1640 channel_bag->channel_group_move(group0, 0);
1641 EXPECT_EQ(&group0, channel_bag->channel_group(0));
1642 EXPECT_EQ(&group2, channel_bag->channel_group(1));
1643 EXPECT_EQ(&group1, channel_bag->channel_group(2));
1650 EXPECT_EQ(&fcu0, channel_bag->fcurve(0));
1651 EXPECT_EQ(&fcu3, channel_bag->fcurve(1));
1652 EXPECT_EQ(&fcu1, channel_bag->fcurve(2));
1653 EXPECT_EQ(&fcu2, channel_bag->fcurve(3));
1654 EXPECT_EQ(&fcu4, channel_bag->fcurve(4));
1664 FCurve &fcu0 = channel_bag->fcurve_ensure(
nullptr, {
"fcu0", 0, std::nullopt, std::nullopt});
1665 FCurve &fcu1 = channel_bag->fcurve_ensure(
nullptr, {
"fcu1", 0, std::nullopt, std::nullopt});
1666 FCurve &fcu2 = channel_bag->fcurve_ensure(
nullptr, {
"fcu2", 0, std::nullopt, std::nullopt});
1667 bActionGroup &group0 = channel_bag->channel_group_create(
"group0");
1668 bActionGroup &group1 = channel_bag->channel_group_create(
"group1");
1670 ASSERT_EQ(3, channel_bag->fcurves().size());
1671 EXPECT_EQ(&fcu0, channel_bag->fcurve(0));
1672 EXPECT_EQ(&fcu1, channel_bag->fcurve(1));
1673 EXPECT_EQ(&fcu2, channel_bag->fcurve(2));
1674 ASSERT_EQ(2, channel_bag->channel_groups().size());
1675 EXPECT_EQ(&group0, channel_bag->channel_group(0));
1676 EXPECT_EQ(&group1, channel_bag->channel_group(1));
1682 channel_bag->fcurve_assign_to_channel_group(fcu2, group1);
1683 EXPECT_EQ(&fcu2, channel_bag->fcurve(0));
1684 EXPECT_EQ(&fcu0, channel_bag->fcurve(1));
1685 EXPECT_EQ(&fcu1, channel_bag->fcurve(2));
1691 channel_bag->fcurve_assign_to_channel_group(fcu1, group0);
1692 EXPECT_EQ(&fcu1, channel_bag->fcurve(0));
1693 EXPECT_EQ(&fcu2, channel_bag->fcurve(1));
1694 EXPECT_EQ(&fcu0, channel_bag->fcurve(2));
1700 channel_bag->fcurve_assign_to_channel_group(fcu0, group1);
1701 EXPECT_EQ(&fcu1, channel_bag->fcurve(0));
1702 EXPECT_EQ(&fcu2, channel_bag->fcurve(1));
1703 EXPECT_EQ(&fcu0, channel_bag->fcurve(2));
1709 channel_bag->fcurve_assign_to_channel_group(fcu0, group0);
1710 EXPECT_EQ(&fcu1, channel_bag->fcurve(0));
1711 EXPECT_EQ(&fcu0, channel_bag->fcurve(1));
1712 EXPECT_EQ(&fcu2, channel_bag->fcurve(2));
1718 channel_bag->fcurve_assign_to_channel_group(fcu1, group1);
1719 EXPECT_EQ(&fcu0, channel_bag->fcurve(0));
1720 EXPECT_EQ(&fcu2, channel_bag->fcurve(1));
1721 EXPECT_EQ(&fcu1, channel_bag->fcurve(2));
1730 FCurve &fcu0 = channel_bag->fcurve_ensure(
nullptr, {
"fcu0", 0, std::nullopt,
"group0"});
1731 FCurve &fcu1 = channel_bag->fcurve_ensure(
nullptr, {
"fcu1", 0, std::nullopt,
"group0"});
1732 FCurve &fcu2 = channel_bag->fcurve_ensure(
nullptr, {
"fcu2", 0, std::nullopt,
"group1"});
1733 FCurve &fcu3 = channel_bag->fcurve_ensure(
nullptr, {
"fcu3", 0, std::nullopt,
"group1"});
1734 FCurve &fcu4 = channel_bag->fcurve_ensure(
nullptr, {
"fcu4", 0, std::nullopt, std::nullopt});
1736 ASSERT_EQ(5, channel_bag->fcurves().size());
1737 ASSERT_EQ(2, channel_bag->channel_groups().size());
1744 EXPECT_FALSE(channel_bag->fcurve_ungroup(bogus));
1747 EXPECT_TRUE(channel_bag->fcurve_ungroup(fcu4));
1751 EXPECT_TRUE(channel_bag->fcurve_ungroup(fcu0));
1756 EXPECT_EQ(&fcu1, channel_bag->fcurve(0));
1757 EXPECT_EQ(&fcu2, channel_bag->fcurve(1));
1758 EXPECT_EQ(&fcu3, channel_bag->fcurve(2));
1759 EXPECT_EQ(&fcu4, channel_bag->fcurve(3));
1760 EXPECT_EQ(&fcu0, channel_bag->fcurve(4));
1767 EXPECT_TRUE(channel_bag->fcurve_ungroup(fcu3));
1772 EXPECT_EQ(&fcu1, channel_bag->fcurve(0));
1773 EXPECT_EQ(&fcu2, channel_bag->fcurve(1));
1774 EXPECT_EQ(&fcu4, channel_bag->fcurve(2));
1775 EXPECT_EQ(&fcu0, channel_bag->fcurve(3));
1776 EXPECT_EQ(&fcu3, channel_bag->fcurve(4));
1783 EXPECT_TRUE(channel_bag->fcurve_ungroup(fcu1));
1784 EXPECT_EQ(1, channel_bag->channel_groups().size());
1785 EXPECT_EQ(&group1, channel_bag->channel_group(0));
1788 EXPECT_EQ(&fcu2, channel_bag->fcurve(0));
1789 EXPECT_EQ(&fcu4, channel_bag->fcurve(1));
1790 EXPECT_EQ(&fcu0, channel_bag->fcurve(2));
1791 EXPECT_EQ(&fcu3, channel_bag->fcurve(3));
1792 EXPECT_EQ(&fcu1, channel_bag->fcurve(4));
1799 EXPECT_TRUE(channel_bag->fcurve_ungroup(fcu2));
1800 EXPECT_EQ(0, channel_bag->channel_groups().size());
1801 EXPECT_EQ(&fcu4, channel_bag->fcurve(0));
1802 EXPECT_EQ(&fcu0, channel_bag->fcurve(1));
1803 EXPECT_EQ(&fcu3, channel_bag->fcurve(2));
1804 EXPECT_EQ(&fcu1, channel_bag->fcurve(3));
1805 EXPECT_EQ(&fcu2, channel_bag->fcurve(4));
1858 FCurve *fcurve_to_move = this->fcurve_create(
"source_prop", 2);
1873 <<
"F-Curve should no longer exist in source Action";
1875 <<
"F-Curve should exist in destination Action";
1878 <<
"Source Action should still have the other F-Curve";
1880 <<
"Destination Action should have its original and the moved F-Curve";
1883#ifdef WITH_ANIM_BAKLAVA
1884TEST_F(ActionFCurveMoveTest, test_fcurve_move_layered)
1897 FCurve &fcurve_to_move = cbag_src.fcurve_ensure(this->bmain, {
"source_prop", 2});
1898 bActionGroup &group_src = cbag_src.channel_group_create(
"Gröpje");
1899 cbag_src.fcurve_assign_to_channel_group(fcurve_to_move, group_src);
1902 Slot &slot_dst = action_dst.
slot_add();
1904 StripKeyframeData &strip_data_dst = action_dst.
layer(0)->
strip(0)->
data<StripKeyframeData>(
1906 ChannelBag &cbag_dst = strip_data_dst.channelbag_for_slot_ensure(slot_dst);
1908 cbag_dst.fcurve_ensure(this->bmain, {
"dest_prop", 0});
1918 EXPECT_EQ(
nullptr, cbag_src.fcurve_find({fcurve_to_move.rna_path, fcurve_to_move.array_index}))
1919 <<
"F-Curve should no longer exist in source Action";
1921 cbag_dst.fcurve_find({fcurve_to_move.rna_path, fcurve_to_move.array_index}))
1922 <<
"F-Curve should exist in destination Action";
1924 EXPECT_EQ(1, cbag_src.fcurves().size()) <<
"Source Action should still have the other F-Curve";
1926 <<
"Destination Action should have its original and the moved F-Curve";
1928 bActionGroup *group_dst = cbag_dst.channel_group_find(
"Gröpje");
1929 ASSERT_NE(
nullptr, group_dst) <<
"Expected channel group to be created";
1930 ASSERT_EQ(group_dst, fcurve_to_move.
grp) <<
"Expected group membership to move as well";
Functions and classes to work with Actions.
Blender kernel action and pose functionality.
AnimData * BKE_animdata_ensure_id(ID *id)
FModifier * add_fmodifier(ListBase *modifiers, int type, FCurve *owner_fcu)
FCurve * BKE_fcurve_create(void)
float evaluate_fcurve(const FCurve *fcu, float evaltime)
void BKE_id_free(Main *bmain, void *idv)
void * BKE_id_new(Main *bmain, short type, const char *name)
void * BKE_id_new_nomain(short type, const char *name)
Main * BKE_main_new(void)
void BKE_main_free(Main *bmain)
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_addhead(struct ListBase *listbase, void *vlink) ATTR_NONNULL(1)
void * BLI_poptail(ListBase *listbase) ATTR_NONNULL(1)
void * BLI_findlink(const struct ListBase *listbase, int number) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
void BLI_addtail(struct ListBase *listbase, void *vlink) ATTR_NONNULL(1)
int BLI_findindex(const struct ListBase *listbase, const void *vlink) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
int BLI_listbase_count(const struct ListBase *listbase) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
char * BLI_strdupn(const char *str, size_t len) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
#define STRNCPY_UTF8(dst, src)
struct bActionGroup bActionGroup
Object is a sort of wrapper for general info.
Group Output data from inside of a node group A color picker Mix two input colors RGB to Convert a color s luminance to a grayscale value Generate a normal vector and a dot product Brightness Control the brightness and contrast of the input color Vector Map input vector components with curves Camera Retrieve information about the camera and how it relates to the current shading point s position Clamp a value between a minimum and a maximum Vector Perform vector math operation Invert Invert a producing a negative Combine Generate a color from its and blue channels(Deprecated)") DefNode(ShaderNode
constexpr bool contains(const T &value) const
bool contains(const T &value) const
constexpr const char * c_str() const
void layer_keystrip_ensure()
const Layer * layer(int64_t index) const
const Slot * slot(int64_t index) const
bool is_action_legacy() const
bool is_action_layered() const
float2 get_frame_range_of_keys(bool include_modifiers) const ATTR_WARN_UNUSED_RESULT
Layer & layer_add(std::optional< StringRefNull > name)
const bActionGroup * channel_group(int64_t index) const
FCurve & fcurve_ensure(Main *bmain, FCurveDescriptor fcurve_descriptor)
FCurve * fcurve_create_unique(Main *bmain, FCurveDescriptor fcurve_descriptor)
void fcurve_append(FCurve &fcurve)
blender::Span< const bActionGroup * > channel_groups() const
bool strip_remove(Action &owning_action, Strip &strip)
blender::Span< const Strip * > strips() const
const Strip * strip(int64_t index) const
Strip & strip_add(Action &owning_action, Strip::Type strip_type)
std::string name_prefix_for_idtype() const
Vector< ID * > runtime_users()
void name_ensure_prefix()
Span< ID * > users(Main &bmain) const
static constexpr slot_handle_t unassigned
const ChannelBag * channelbag(int64_t index) const
ChannelBag & channelbag_for_slot_ensure(const Slot &slot)
SingleKeyingResult keyframe_insert(Main *bmain, const Slot &slot, FCurveDescriptor fcurve_descriptor, float2 time_value, const KeyframeSettings &settings, eInsertKeyFlags insert_key_flags=INSERTKEY_NOFLAGS)
const ChannelBag * channelbag_for_slot(const Slot &slot) const
blender::Span< const ChannelBag * > channelbags() const
bool is_last_frame(float frame_time) const
void resize(float frame_start, float frame_end)
const T & data(const Action &owning_action) const
bool contains_frame(float frame_time) const
static FCurve * fcurve_create(const StringRefNull rna_path, const int array_index)
static void TearDownTestSuite()
static void SetUpTestSuite()
static void SetUpTestSuite()
static void TearDownTestSuite()
static void TearDownTestSuite()
static void SetUpTestSuite()
static void SetUpTestSuite()
static void TearDownTestSuite()
static void add_fcurve_to_action(Action &action, FCurve &fcu)
static void allocate_keyframes(FCurve &fcu, const size_t num_keyframes)
TEST_F(ActionIteratorsTest, iterate_all_fcurves_of_slot)
static void add_keyframe(FCurve &fcu, float x, float y)
KeyframeSettings get_keyframe_settings(bool from_userprefs)
Slot * assign_action_ensure_slot_for_keying(Action &action, ID &animated_id)
FCurve * action_fcurve_ensure(Main *bmain, bAction *act, const char group[], PointerRNA *ptr, FCurveDescriptor fcurve_descriptor)
void action_fcurve_move(Action &action_dst, slot_handle_t action_slot_dst, Action &action_src, FCurve &fcurve)
Action & action_add(Main &bmain, StringRefNull name)
ActionSlotAssignmentResult assign_action_and_slot(Action *action, Slot *slot_to_assign, ID &animated_id)
SingleKeyingResult insert_vert_fcurve(FCurve *fcu, const float2 position, const KeyframeSettings &settings, eInsertKeyFlags flag)
Main Key-framing API call.
ID * action_slot_get_id_for_keying(Main &bmain, Action &action, slot_handle_t slot_handle, ID *primary_id)
bool is_action_assignable_to(const bAction *dna_action, ID_Type id_code) ATTR_WARN_UNUSED_RESULT
decltype(::ActionSlot::handle) slot_handle_t
Action * convert_to_layered_action(Main &bmain, const Action &legacy_action)
bool unassign_action(ID &animated_id)
bool assign_action(bAction *action, ID &animated_id)
ActionSlotAssignmentResult assign_action_slot(Slot *slot_to_assign, ID &animated_id)
void move_slot(Main &bmain, Slot &slot, Action &from_action, Action &to_action)
VecBase< float, 2 > float2
PointerRNA RNA_id_pointer_create(ID *id)
struct FCurve ** fcurve_array
ActionSlotRuntimeHandle * runtime