Refactor: bundle fcurve lookup/creation parameters in a struct

This is a follow up to #123022 to clean up the resultant verbose parameter
passing.  We add a new struct `FCurveDescriptor` that contains the parameters
needed for either looking up or creating an fcurve, and that in turn is passed
down the keyframing call chains where fcurve lookup/creation needs to be done.

Pull Request: https://projects.blender.org/blender/blender/pulls/123486
This commit is contained in:
Nathan Vegdahl
2024-06-28 09:39:51 +02:00
committed by Nathan Vegdahl
parent bea0c5c914
commit cae1faec12
13 changed files with 107 additions and 103 deletions

View File

@@ -535,7 +535,7 @@ class KeyframeStrip : public ::KeyframeActionStrip {
*
* If it cannot be found, `nullptr` is returned.
*/
FCurve *fcurve_find(const Binding &binding, StringRefNull rna_path, int array_index);
FCurve *fcurve_find(const Binding &binding, FCurveDescriptor fcurve_descriptor);
/**
* Find an FCurve for this binding + RNA path + array index combination.
@@ -545,15 +545,10 @@ class KeyframeStrip : public ::KeyframeActionStrip {
* \param `prop_subtype` The subtype of the property this fcurve is for, if
* available.
*/
FCurve &fcurve_find_or_create(const Binding &binding,
StringRefNull rna_path,
int array_index,
std::optional<PropertySubType> prop_subtype);
FCurve &fcurve_find_or_create(const Binding &binding, FCurveDescriptor fcurve_descriptor);
SingleKeyingResult keyframe_insert(const Binding &binding,
StringRefNull rna_path,
int array_index,
std::optional<PropertySubType> prop_subtype,
FCurveDescriptor fcurve_descriptor,
float2 time_value,
const KeyframeSettings &settings,
eInsertKeyFlags insert_key_flags = INSERTKEY_NOFLAGS);
@@ -670,13 +665,12 @@ FCurve *action_fcurve_ensure(Main *bmain,
bAction *act,
const char group[],
PointerRNA *ptr,
const char rna_path[],
int array_index);
FCurveDescriptor fcurve_descriptor);
/**
* Find the F-Curve from the given Action. This assumes that all the destinations are valid.
*/
FCurve *action_fcurve_find(bAction *act, const char rna_path[], int array_index);
FCurve *action_fcurve_find(bAction *act, FCurveDescriptor fcurve_descriptor);
} // namespace blender::animrig

View File

@@ -23,6 +23,13 @@ struct FCurve;
namespace blender::animrig {
/* All the information needed to look up or create an FCurve. */
struct FCurveDescriptor {
StringRefNull rna_path;
int array_index;
std::optional<PropertySubType> prop_subtype;
};
/* This is used to pass in the settings for a keyframe into a function. */
struct KeyframeSettings {
eBezTriple_KeyframeType keyframe_type;
@@ -45,9 +52,7 @@ KeyframeSettings get_keyframe_settings(bool from_userprefs);
* If the channel's property subtype is provided, the fcurve will also be set to
* the correct color mode based on user preferences.
*/
FCurve *create_fcurve_for_channel(StringRef rna_path,
int array_index,
std::optional<PropertySubType> prop_subtype);
FCurve *create_fcurve_for_channel(FCurveDescriptor fcurve_descriptor);
/** Initialize the given BezTriple with default values. */
void initialize_bezt(BezTriple *beztr,

View File

@@ -906,8 +906,7 @@ ChannelBag &KeyframeStrip::channelbag_for_binding_add(const Binding &binding)
}
FCurve *KeyframeStrip::fcurve_find(const Binding &binding,
const StringRefNull rna_path,
const int array_index)
const FCurveDescriptor fcurve_descriptor)
{
ChannelBag *channels = this->channelbag_for_binding(binding);
if (channels == nullptr) {
@@ -920,7 +919,9 @@ FCurve *KeyframeStrip::fcurve_find(const Binding &binding,
for (FCurve *fcu : channels->fcurves()) {
/* Check indices first, much cheaper than a string comparison. */
/* Simple string-compare (this assumes that they have the same root...) */
if (fcu->array_index == array_index && fcu->rna_path && StringRef(fcu->rna_path) == rna_path) {
if (fcu->array_index == fcurve_descriptor.array_index && fcu->rna_path &&
StringRef(fcu->rna_path) == fcurve_descriptor.rna_path)
{
return fcu;
}
}
@@ -928,15 +929,13 @@ FCurve *KeyframeStrip::fcurve_find(const Binding &binding,
}
FCurve &KeyframeStrip::fcurve_find_or_create(const Binding &binding,
const StringRefNull rna_path,
const int array_index,
const std::optional<PropertySubType> prop_subtype)
const FCurveDescriptor fcurve_descriptor)
{
if (FCurve *existing_fcurve = this->fcurve_find(binding, rna_path, array_index)) {
if (FCurve *existing_fcurve = this->fcurve_find(binding, fcurve_descriptor)) {
return *existing_fcurve;
}
FCurve *new_fcurve = create_fcurve_for_channel(rna_path.c_str(), array_index, prop_subtype);
FCurve *new_fcurve = create_fcurve_for_channel(fcurve_descriptor);
ChannelBag *channels = this->channelbag_for_binding(binding);
if (channels == nullptr) {
@@ -951,26 +950,23 @@ FCurve &KeyframeStrip::fcurve_find_or_create(const Binding &binding,
return *new_fcurve;
}
SingleKeyingResult KeyframeStrip::keyframe_insert(
const Binding &binding,
const StringRefNull rna_path,
const int array_index,
const std::optional<PropertySubType> prop_subtype,
const float2 time_value,
const KeyframeSettings &settings,
const eInsertKeyFlags insert_key_flags)
SingleKeyingResult KeyframeStrip::keyframe_insert(const Binding &binding,
const FCurveDescriptor fcurve_descriptor,
const float2 time_value,
const KeyframeSettings &settings,
const eInsertKeyFlags insert_key_flags)
{
/* Get the fcurve, or create one if it doesn't exist and the keying flags
* allow. */
FCurve *fcurve = key_insertion_may_create_fcurve(insert_key_flags) ?
&this->fcurve_find_or_create(binding, rna_path, array_index, prop_subtype) :
this->fcurve_find(binding, rna_path, array_index);
&this->fcurve_find_or_create(binding, fcurve_descriptor) :
this->fcurve_find(binding, fcurve_descriptor);
if (!fcurve) {
std::fprintf(stderr,
"FCurve %s[%d] for binding %s was not created due to either the Only Insert "
"Available setting or Replace keyframing mode.\n",
rna_path.c_str(),
array_index,
fcurve_descriptor.rna_path.c_str(),
fcurve_descriptor.array_index,
binding.name);
return SingleKeyingResult::CANNOT_CREATE_FCURVE;
}
@@ -979,8 +975,8 @@ SingleKeyingResult KeyframeStrip::keyframe_insert(
/* TODO: handle this properly, in a way that can be communicated to the user. */
std::fprintf(stderr,
"FCurve %s[%d] for binding %s doesn't allow inserting keys.\n",
rna_path.c_str(),
array_index,
fcurve_descriptor.rna_path.c_str(),
fcurve_descriptor.array_index,
binding.name);
return SingleKeyingResult::FCURVE_NOT_KEYFRAMEABLE;
}
@@ -991,8 +987,8 @@ SingleKeyingResult KeyframeStrip::keyframe_insert(
if (insert_vert_result != SingleKeyingResult::SUCCESS) {
std::fprintf(stderr,
"Could not insert key into FCurve %s[%d] for binding %s.\n",
rna_path.c_str(),
array_index,
fcurve_descriptor.rna_path.c_str(),
fcurve_descriptor.array_index,
binding.name);
return insert_vert_result;
}
@@ -1163,22 +1159,22 @@ Vector<const FCurve *> fcurves_all(const Action &action)
const ChannelBag>(action);
}
FCurve *action_fcurve_find(bAction *act, const char rna_path[], const int array_index)
FCurve *action_fcurve_find(bAction *act, FCurveDescriptor fcurve_descriptor)
{
if (ELEM(nullptr, act, rna_path)) {
if (act == nullptr) {
return nullptr;
}
return BKE_fcurve_find(&act->curves, rna_path, array_index);
return BKE_fcurve_find(
&act->curves, fcurve_descriptor.rna_path.c_str(), fcurve_descriptor.array_index);
}
FCurve *action_fcurve_ensure(Main *bmain,
bAction *act,
const char group[],
PointerRNA *ptr,
const char rna_path[],
const int array_index)
FCurveDescriptor fcurve_descriptor)
{
if (ELEM(nullptr, act, rna_path)) {
if (act == nullptr) {
return nullptr;
}
@@ -1186,7 +1182,8 @@ FCurve *action_fcurve_ensure(Main *bmain,
* - add if not found and allowed to add one
* TODO: add auto-grouping support? how this works will need to be resolved
*/
FCurve *fcu = BKE_fcurve_find(&act->curves, rna_path, array_index);
FCurve *fcu = BKE_fcurve_find(
&act->curves, fcurve_descriptor.rna_path.c_str(), fcurve_descriptor.array_index);
if (fcu != nullptr) {
return fcu;
@@ -1199,13 +1196,17 @@ FCurve *action_fcurve_ensure(Main *bmain,
PointerRNA resolved_ptr;
PointerRNA id_ptr = RNA_id_pointer_create(ptr->owner_id);
const bool resolved = RNA_path_resolve_property(
&id_ptr, rna_path, &resolved_ptr, &resolved_prop);
&id_ptr, fcurve_descriptor.rna_path.c_str(), &resolved_ptr, &resolved_prop);
if (resolved) {
prop_subtype = RNA_property_subtype(resolved_prop);
}
}
fcu = create_fcurve_for_channel(rna_path, array_index, prop_subtype);
BLI_assert_msg(!fcurve_descriptor.prop_subtype.has_value(),
"Did not expect a prop_subtype to be passed in. This is fine, but does need some "
"changes to action_fcurve_ensure() to deal with it");
fcu = create_fcurve_for_channel(
{fcurve_descriptor.rna_path, fcurve_descriptor.array_index, prop_subtype});
if (BLI_listbase_is_empty(&act->curves)) {
fcu->flag |= FCURVE_ACTIVE;

View File

@@ -141,10 +141,9 @@ TEST_F(ActionLayersTest, add_strip)
/* Add some keys to check that also the strip data is freed correctly. */
const KeyframeSettings settings = get_keyframe_settings(false);
Binding &binding = anim->binding_add();
strip.as<KeyframeStrip>().keyframe_insert(
binding, "location", 0, std::nullopt, {1.0f, 47.0f}, settings);
strip.as<KeyframeStrip>().keyframe_insert(binding, {"location", 0}, {1.0f, 47.0f}, settings);
another_strip.as<KeyframeStrip>().keyframe_insert(
binding, "location", 0, std::nullopt, {1.0f, 47.0f}, settings);
binding, {"location", 0}, {1.0f, 47.0f}, settings);
}
TEST_F(ActionLayersTest, remove_strip)
@@ -157,12 +156,9 @@ TEST_F(ActionLayersTest, remove_strip)
/* Add some keys to check that also the strip data is freed correctly. */
const KeyframeSettings settings = get_keyframe_settings(false);
Binding &binding = anim->binding_add();
strip0.as<KeyframeStrip>().keyframe_insert(
binding, "location", 0, std::nullopt, {1.0f, 47.0f}, settings);
strip1.as<KeyframeStrip>().keyframe_insert(
binding, "location", 0, std::nullopt, {1.0f, 47.0f}, settings);
strip2.as<KeyframeStrip>().keyframe_insert(
binding, "location", 0, std::nullopt, {1.0f, 47.0f}, settings);
strip0.as<KeyframeStrip>().keyframe_insert(binding, {"location", 0}, {1.0f, 47.0f}, settings);
strip1.as<KeyframeStrip>().keyframe_insert(binding, {"location", 0}, {1.0f, 47.0f}, settings);
strip2.as<KeyframeStrip>().keyframe_insert(binding, {"location", 0}, {1.0f, 47.0f}, settings);
EXPECT_TRUE(layer.strip_remove(strip1));
EXPECT_EQ(2, layer.strips().size());
@@ -478,7 +474,7 @@ TEST_F(ActionLayersTest, KeyframeStrip__keyframe_insert)
const KeyframeSettings settings = get_keyframe_settings(false);
SingleKeyingResult result_loc_a = key_strip.keyframe_insert(
binding, "location", 0, std::nullopt, {1.0f, 47.0f}, settings);
binding, {"location", 0}, {1.0f, 47.0f}, settings);
ASSERT_EQ(SingleKeyingResult::SUCCESS, result_loc_a)
<< "Expected keyframe insertion to be successful";
@@ -489,7 +485,7 @@ TEST_F(ActionLayersTest, KeyframeStrip__keyframe_insert)
/* Insert a second key, should insert into the same FCurve as before. */
SingleKeyingResult result_loc_b = key_strip.keyframe_insert(
binding, "location", 0, std::nullopt, {5.0f, 47.1f}, settings);
binding, {"location", 0}, {5.0f, 47.1f}, settings);
EXPECT_EQ(SingleKeyingResult::SUCCESS, result_loc_b);
ASSERT_EQ(1, channels->fcurves().size()) << "Expect insertion with the same (binding/rna "
"path/array index) tuple to go into the same FCurve";
@@ -502,7 +498,7 @@ TEST_F(ActionLayersTest, KeyframeStrip__keyframe_insert)
/* Insert another key for another property, should create another FCurve. */
SingleKeyingResult result_rot = key_strip.keyframe_insert(
binding, "rotation_quaternion", 0, std::nullopt, {1.0f, 0.25f}, settings);
binding, {"rotation_quaternion", 0}, {1.0f, 0.25f}, settings);
EXPECT_EQ(SingleKeyingResult::SUCCESS, result_rot);
ASSERT_EQ(2, channels->fcurves().size()) << "Expected a second FCurve to be created.";
EXPECT_EQ(2, channels->fcurves()[0]->totvert);

View File

@@ -149,10 +149,10 @@ TEST_F(AnimationEvaluationTest, evaluate_layer__keyframes)
KeyframeStrip &key_strip = strip.as<KeyframeStrip>();
/* Set some keys. */
key_strip.keyframe_insert(*binding, "location", 0, std::nullopt, {1.0f, 47.1f}, settings);
key_strip.keyframe_insert(*binding, "location", 0, std::nullopt, {5.0f, 47.5f}, settings);
key_strip.keyframe_insert(*binding, "rotation_euler", 1, std::nullopt, {1.0f, 0.0f}, settings);
key_strip.keyframe_insert(*binding, "rotation_euler", 1, std::nullopt, {5.0f, 3.14f}, settings);
key_strip.keyframe_insert(*binding, {"location", 0}, {1.0f, 47.1f}, settings);
key_strip.keyframe_insert(*binding, {"location", 0}, {5.0f, 47.5f}, settings);
key_strip.keyframe_insert(*binding, {"rotation_euler", 1}, {1.0f, 0.0f}, settings);
key_strip.keyframe_insert(*binding, {"rotation_euler", 1}, {5.0f, 3.14f}, settings);
/* Set the animated properties to some values. These should not be overwritten
* by the evaluation itself. */
@@ -190,9 +190,9 @@ TEST_F(AnimationEvaluationTest, strip_boundaries__single_strip)
/* Set some keys. */
KeyframeStrip &key_strip = strip.as<KeyframeStrip>();
key_strip.keyframe_insert(*binding, "location", 0, std::nullopt, {1.0f, 47.0f}, settings);
key_strip.keyframe_insert(*binding, "location", 0, std::nullopt, {5.0f, 327.0f}, settings);
key_strip.keyframe_insert(*binding, "location", 0, std::nullopt, {10.0f, 48.0f}, settings);
key_strip.keyframe_insert(*binding, {"location", 0}, {1.0f, 47.0f}, settings);
key_strip.keyframe_insert(*binding, {"location", 0}, {5.0f, 327.0f}, settings);
key_strip.keyframe_insert(*binding, {"location", 0}, {10.0f, 48.0f}, settings);
/* Evaluate the layer to see how it handles the boundaries + something in between. */
EXPECT_TRUE(test_evaluate_layer("location", 0, {1.0f, 47.0f}));
@@ -214,15 +214,15 @@ TEST_F(AnimationEvaluationTest, strip_boundaries__nonoverlapping)
/* Set some keys. */
{
KeyframeStrip &key_strip1 = strip1.as<KeyframeStrip>();
key_strip1.keyframe_insert(*binding, "location", 0, std::nullopt, {1.0f, 47.0f}, settings);
key_strip1.keyframe_insert(*binding, "location", 0, std::nullopt, {5.0f, 327.0f}, settings);
key_strip1.keyframe_insert(*binding, "location", 0, std::nullopt, {10.0f, 48.0f}, settings);
key_strip1.keyframe_insert(*binding, {"location", 0}, {1.0f, 47.0f}, settings);
key_strip1.keyframe_insert(*binding, {"location", 0}, {5.0f, 327.0f}, settings);
key_strip1.keyframe_insert(*binding, {"location", 0}, {10.0f, 48.0f}, settings);
}
{
KeyframeStrip &key_strip2 = strip2.as<KeyframeStrip>();
key_strip2.keyframe_insert(*binding, "location", 0, std::nullopt, {1.0f, 47.0f}, settings);
key_strip2.keyframe_insert(*binding, "location", 0, std::nullopt, {5.0f, 327.0f}, settings);
key_strip2.keyframe_insert(*binding, "location", 0, std::nullopt, {10.0f, 48.0f}, settings);
key_strip2.keyframe_insert(*binding, {"location", 0}, {1.0f, 47.0f}, settings);
key_strip2.keyframe_insert(*binding, {"location", 0}, {5.0f, 327.0f}, settings);
key_strip2.keyframe_insert(*binding, {"location", 0}, {10.0f, 48.0f}, settings);
}
/* Check Strip 1. */
@@ -254,15 +254,15 @@ TEST_F(AnimationEvaluationTest, strip_boundaries__overlapping_edge)
/* Set some keys. */
{
KeyframeStrip &key_strip1 = strip1.as<KeyframeStrip>();
key_strip1.keyframe_insert(*binding, "location", 0, std::nullopt, {1.0f, 47.0f}, settings);
key_strip1.keyframe_insert(*binding, "location", 0, std::nullopt, {5.0f, 327.0f}, settings);
key_strip1.keyframe_insert(*binding, "location", 0, std::nullopt, {10.0f, 48.0f}, settings);
key_strip1.keyframe_insert(*binding, {"location", 0}, {1.0f, 47.0f}, settings);
key_strip1.keyframe_insert(*binding, {"location", 0}, {5.0f, 327.0f}, settings);
key_strip1.keyframe_insert(*binding, {"location", 0}, {10.0f, 48.0f}, settings);
}
{
KeyframeStrip &key_strip2 = strip2.as<KeyframeStrip>();
key_strip2.keyframe_insert(*binding, "location", 0, std::nullopt, {1.0f, 47.0f}, settings);
key_strip2.keyframe_insert(*binding, "location", 0, std::nullopt, {5.0f, 327.0f}, settings);
key_strip2.keyframe_insert(*binding, "location", 0, std::nullopt, {10.0f, 48.0f}, settings);
key_strip2.keyframe_insert(*binding, {"location", 0}, {1.0f, 47.0f}, settings);
key_strip2.keyframe_insert(*binding, {"location", 0}, {5.0f, 327.0f}, settings);
key_strip2.keyframe_insert(*binding, {"location", 0}, {10.0f, 48.0f}, settings);
}
/* Check Strip 1. */

View File

@@ -35,19 +35,18 @@ KeyframeSettings get_keyframe_settings(const bool from_userprefs)
return settings;
}
FCurve *create_fcurve_for_channel(const StringRef rna_path,
const int array_index,
const std::optional<PropertySubType> prop_subtype)
FCurve *create_fcurve_for_channel(const FCurveDescriptor fcurve_descriptor)
{
FCurve *fcu = BKE_fcurve_create();
fcu->rna_path = BLI_strdupn(rna_path.data(), rna_path.size());
fcu->array_index = array_index;
fcu->rna_path = BLI_strdupn(fcurve_descriptor.rna_path.data(),
fcurve_descriptor.rna_path.size());
fcu->array_index = fcurve_descriptor.array_index;
fcu->flag = (FCURVE_VISIBLE | FCURVE_SELECTED);
fcu->auto_smoothing = U.auto_smoothing_new;
/* Set the fcurve's color mode if needed/able. */
if ((U.keying_flag & KEYING_FLAG_XYZ2RGB) != 0 && prop_subtype.has_value()) {
switch (*prop_subtype) {
if ((U.keying_flag & KEYING_FLAG_XYZ2RGB) != 0 && fcurve_descriptor.prop_subtype.has_value()) {
switch (*fcurve_descriptor.prop_subtype) {
case PROP_TRANSLATION:
case PROP_XYZ:
case PROP_EULER:

View File

@@ -563,14 +563,16 @@ static SingleKeyingResult insert_keyframe_fcurve_value(Main *bmain,
eBezTriple_KeyframeType keytype,
eInsertKeyFlags flag)
{
BLI_assert(rna_path != nullptr);
/* Make sure the F-Curve exists.
* - if we're replacing keyframes only, DO NOT create new F-Curves if they do not exist yet
* but still try to get the F-Curve if it exists...
*/
FCurve *fcu = key_insertion_may_create_fcurve(flag) ?
action_fcurve_ensure(bmain, act, group, ptr, rna_path, array_index) :
action_fcurve_find(act, rna_path, array_index);
action_fcurve_ensure(bmain, act, group, ptr, {rna_path, array_index}) :
action_fcurve_find(act, {rna_path, array_index});
/* We may not have a F-Curve when we're replacing only. */
if (!fcu) {
@@ -633,6 +635,7 @@ int delete_keyframe(Main *bmain,
int array_index,
float cfra)
{
BLI_assert(rna_path != nullptr);
AnimData *adt = BKE_animdata_from_id(id);
if (ELEM(nullptr, id, adt)) {
@@ -682,7 +685,7 @@ int delete_keyframe(Main *bmain,
/* Will only loop once unless the array index was -1. */
int key_count = 0;
for (; array_index < array_index_max; array_index++) {
FCurve *fcu = action_fcurve_find(act, rna_path, array_index);
FCurve *fcu = action_fcurve_find(act, {rna_path, array_index});
if (fcu == nullptr) {
continue;
@@ -718,6 +721,8 @@ int clear_keyframe(Main *bmain,
int array_index,
eInsertKeyFlags /*flag*/)
{
BLI_assert(rna_path != nullptr);
AnimData *adt = BKE_animdata_from_id(id);
if (ELEM(nullptr, id, adt)) {
@@ -765,7 +770,7 @@ int clear_keyframe(Main *bmain,
int key_count = 0;
/* Will only loop once unless the array index was -1. */
for (; array_index < array_index_max; array_index++) {
FCurve *fcu = action_fcurve_find(act, rna_path, array_index);
FCurve *fcu = action_fcurve_find(act, {rna_path, array_index});
if (fcu == nullptr) {
continue;
@@ -866,9 +871,7 @@ static SingleKeyingResult insert_key_layer(Layer &layer,
BLI_assert(strip->frame_offset == 0.0);
return strip->as<KeyframeStrip>().keyframe_insert(binding,
rna_path,
key_data.array_index,
prop_subtype,
{rna_path, key_data.array_index, prop_subtype},
key_data.position,
key_settings,
insert_key_flags);
@@ -1031,6 +1034,9 @@ CombinedKeyingResult insert_keyframes(Main *bmain,
const std::optional<std::string> rna_path_id_to_prop = RNA_path_from_ID_to_property(&ptr,
prop);
if (!rna_path_id_to_prop.has_value()) {
continue;
}
/* Handle the `force_all` condition mentioned above, ensuring the
* "all-or-nothing" behavior if needed.
@@ -1047,7 +1053,7 @@ CombinedKeyingResult insert_keyframes(Main *bmain,
/* Determine if at least one element would succeed getting keyed. */
bool at_least_one_would_succeed = false;
for (int i = 0; i < rna_values.size(); i++) {
const FCurve *fcu = action_fcurve_find(action, rna_path_id_to_prop->c_str(), i);
const FCurve *fcu = action_fcurve_find(action, {*rna_path_id_to_prop, i});
if (!fcu) {
continue;
}

View File

@@ -1316,7 +1316,7 @@ TEST_F(KeyframingTest, insert_keyframes__legacy_action__quaternion_on_nla__only_
/* Create an fcurve and key for a single quaternion channel. */
PointerRNA id_rna_ptr = RNA_id_pointer_create(&object_with_nla->id);
FCurve *fcu = action_fcurve_ensure(
bmain, nla_action, nullptr, &id_rna_ptr, "rotation_quaternion", 0);
bmain, nla_action, nullptr, &id_rna_ptr, {"rotation_quaternion", 0});
const KeyframeSettings keyframe_settings = {BEZT_KEYTYPE_KEYFRAME, HD_AUTO_ANIM, BEZT_IPO_BEZ};
insert_vert_fcurve(fcu, {1.0, 1.0}, keyframe_settings, INSERTKEY_NOFLAGS);
@@ -1356,7 +1356,7 @@ TEST_F(KeyframingTest, insert_keyframes__legacy_action__quaternion_on_nla__only_
/* Directly create an fcurve and key for a single quaternion channel. */
PointerRNA id_rna_ptr = RNA_id_pointer_create(&object_with_nla->id);
FCurve *fcu = action_fcurve_ensure(
bmain, nla_action, nullptr, &id_rna_ptr, "rotation_quaternion", 0);
bmain, nla_action, nullptr, &id_rna_ptr, {"rotation_quaternion", 0});
const KeyframeSettings keyframe_settings = {BEZT_KEYTYPE_KEYFRAME, HD_AUTO_ANIM, BEZT_IPO_BEZ};
insert_vert_fcurve(fcu, {11.0, 1.0}, keyframe_settings, INSERTKEY_NOFLAGS);

View File

@@ -515,7 +515,7 @@ static void gpencil_stroke_path_animation(bContext *C,
/* Ensure we have an F-Curve to add keyframes to */
act = blender::animrig::id_action_ensure(bmain, (ID *)cu);
fcu = blender::animrig::action_fcurve_ensure(bmain, act, nullptr, &ptr, "eval_time", 0);
fcu = blender::animrig::action_fcurve_ensure(bmain, act, nullptr, &ptr, {"eval_time", 0});
if (gtd->mode == GP_STROKECONVERT_TIMING_LINEAR) {
float cfra;

View File

@@ -112,7 +112,7 @@ class CopyDriversToSelected : public testing::Test {
PointerRNA cube_ptr = RNA_pointer_create(&cube->id, &RNA_Object, &cube->id);
bAction *act = animrig::id_action_ensure(bmain, &cube->id);
FCurve *fcu = animrig::action_fcurve_ensure(
bmain, act, "Object Transforms", &cube_ptr, "rotation_quaternion", 3);
bmain, act, "Object Transforms", &cube_ptr, {"rotation_quaternion", 3});
animrig::KeyframeSettings keyframe_settings = {BEZT_KEYTYPE_KEYFRAME, HD_AUTO, BEZT_IPO_BEZ};
insert_vert_fcurve(fcu, {1.0, 1.0}, keyframe_settings, INSERTKEY_NOFLAGS);
}

View File

@@ -1074,7 +1074,7 @@ static int followpath_path_animate_exec(bContext *C, wmOperator *op)
{
/* create F-Curve for path animation */
act = animrig::id_action_ensure(bmain, &cu->id);
fcu = animrig::action_fcurve_ensure(bmain, act, nullptr, nullptr, "eval_time", 0);
fcu = animrig::action_fcurve_ensure(bmain, act, nullptr, nullptr, {"eval_time", 0});
/* standard vertical range - 1:1 = 100 frames */
standardRange = 100.0f;
@@ -1094,10 +1094,11 @@ static int followpath_path_animate_exec(bContext *C, wmOperator *op)
prop = RNA_struct_find_property(&ptr, "offset_factor");
const std::optional<std::string> path = RNA_path_from_ID_to_property(&ptr, prop);
BLI_assert(path.has_value());
/* create F-Curve for constraint */
act = animrig::id_action_ensure(bmain, &ob->id);
fcu = animrig::action_fcurve_ensure(bmain, act, nullptr, nullptr, path->c_str(), 0);
fcu = animrig::action_fcurve_ensure(bmain, act, nullptr, nullptr, {path->c_str(), 0});
/* standard vertical range - 0.0 to 1.0 */
standardRange = 1.0f;

View File

@@ -544,7 +544,8 @@ bool parent_set(ReportList *reports,
if (partype == PAR_FOLLOW) {
/* get or create F-Curve */
bAction *act = animrig::id_action_ensure(bmain, &cu->id);
FCurve *fcu = animrig::action_fcurve_ensure(bmain, act, nullptr, nullptr, "eval_time", 0);
FCurve *fcu = animrig::action_fcurve_ensure(
bmain, act, nullptr, nullptr, {"eval_time", 0});
/* setup dummy 'generator' modifier here to get 1-1 correspondence still working */
if (!fcu->bezt && !fcu->fpt && !fcu->modifiers.first) {

View File

@@ -440,7 +440,7 @@ static bool rna_KeyframeActionStrip_key_insert(ID *id,
const animrig::KeyframeSettings settings = animrig::get_keyframe_settings(true);
const animrig::SingleKeyingResult result = key_strip.keyframe_insert(
binding, rna_path, array_index, std::nullopt, {time, value}, settings, INSERTKEY_NOFLAGS);
binding, {rna_path, array_index}, {time, value}, settings, INSERTKEY_NOFLAGS);
const bool ok = result == animrig::SingleKeyingResult::SUCCESS;
if (ok) {
@@ -556,13 +556,14 @@ static FCurve *rna_Action_fcurve_new(bAction *act,
group = nullptr;
}
BLI_assert(data_path != nullptr);
if (data_path[0] == '\0') {
BKE_report(reports, RPT_ERROR, "F-Curve data path empty, invalid argument");
return nullptr;
}
/* Annoying, check if this exists. */
if (blender::animrig::action_fcurve_find(act, data_path, index)) {
if (blender::animrig::action_fcurve_find(act, {data_path, index})) {
BKE_reportf(reports,
RPT_ERROR,
"F-Curve '%s[%d]' already exists in action '%s'",
@@ -571,7 +572,7 @@ static FCurve *rna_Action_fcurve_new(bAction *act,
act->id.name + 2);
return nullptr;
}
return blender::animrig::action_fcurve_ensure(bmain, act, group, nullptr, data_path, index);
return blender::animrig::action_fcurve_ensure(bmain, act, group, nullptr, {data_path, index});
}
static FCurve *rna_Action_fcurve_find(bAction *act,