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:
committed by
Nathan Vegdahl
parent
bea0c5c914
commit
cae1faec12
@@ -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
|
||||
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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. */
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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,
|
||||
|
||||
Reference in New Issue
Block a user