diff --git a/source/blender/animrig/ANIM_action_legacy.hh b/source/blender/animrig/ANIM_action_legacy.hh index 7df85730eb7..0db60037ab2 100644 --- a/source/blender/animrig/ANIM_action_legacy.hh +++ b/source/blender/animrig/ANIM_action_legacy.hh @@ -49,6 +49,14 @@ ChannelBag &channelbag_ensure(Action &action); Vector fcurves_all(const bAction *action); Vector fcurves_all(bAction *action); +/** + * Return the F-Curves for the first slot of this Action. + * + * This works for both legacy and layered Actions. For the former, it will + * return all F-Curves in the Action. + */ +Vector fcurves_first_slot(bAction *action); + /** * Return the F-Curves for this specific slot handle. * diff --git a/source/blender/animrig/intern/action_legacy.cc b/source/blender/animrig/intern/action_legacy.cc index f8cb8a0a845..a2b075cd965 100644 --- a/source/blender/animrig/intern/action_legacy.cc +++ b/source/blender/animrig/intern/action_legacy.cc @@ -124,6 +124,23 @@ Vector fcurves_all(const bAction *action) const ChannelBag>(action->wrap()); } +Vector fcurves_first_slot(bAction *action) +{ + if (!action) { + return {}; + } + Action &action_wrap = action->wrap(); + + if (action_wrap.is_action_legacy()) { + return fcurves_all(action); + } + + if (action_wrap.slots().is_empty()) { + return {}; + } + return fcurves_for_action_slot(action, action_wrap.slot(0)->handle); +} + /* Lots of template args to support transparent non-const and const versions. */ template fcurves); void BKE_fcurve_pathcache_destroy(FCurvePathCache *fcache); FCurve *BKE_fcurve_pathcache_find(FCurvePathCache *fcache, const char rna_path[], int array_index); /** diff --git a/source/blender/blenkernel/intern/action_mirror.cc b/source/blender/blenkernel/intern/action_mirror.cc index 5e3c39bda4a..a035cd7f96e 100644 --- a/source/blender/blenkernel/intern/action_mirror.cc +++ b/source/blender/blenkernel/intern/action_mirror.cc @@ -31,6 +31,8 @@ #include "DEG_depsgraph.hh" +using namespace blender; + /* -------------------------------------------------------------------- */ /** \name Flip the Action (Armature/Pose Objects) * @@ -451,7 +453,8 @@ static void action_flip_pchan_rna_paths(bAction *act) void BKE_action_flip_with_pose(bAction *act, Object *ob_arm) { - FCurvePathCache *fcache = BKE_fcurve_pathcache_create(&act->curves); + Vector fcurves = animrig::legacy::fcurves_first_slot(act); + FCurvePathCache *fcache = BKE_fcurve_pathcache_create(fcurves); int i; LISTBASE_FOREACH_INDEX (bPoseChannel *, pchan, &ob_arm->pose->chanbase, i) { action_flip_pchan(ob_arm, pchan, fcache); diff --git a/source/blender/blenkernel/intern/fcurve_cache.cc b/source/blender/blenkernel/intern/fcurve_cache.cc index fbbafb035ff..ed424d0d4ef 100644 --- a/source/blender/blenkernel/intern/fcurve_cache.cc +++ b/source/blender/blenkernel/intern/fcurve_cache.cc @@ -63,14 +63,13 @@ static int fcurve_cmp_for_cache(const void *fcu_a_p, const void *fcu_b_p) return 0; } -FCurvePathCache *BKE_fcurve_pathcache_create(ListBase *list) +FCurvePathCache *BKE_fcurve_pathcache_create(blender::Span fcurves) { - const uint fcurve_array_len = BLI_listbase_count(list); + const uint fcurve_array_len = fcurves.size(); FCurve **fcurve_array = static_cast( MEM_mallocN(sizeof(*fcurve_array) * fcurve_array_len, __func__)); - uint i; - LISTBASE_FOREACH_INDEX (FCurve *, fcu, list, i) { - fcurve_array[i] = fcu; + for (const int i : fcurves.index_range()) { + fcurve_array[i] = fcurves[i]; } qsort(fcurve_array, fcurve_array_len, sizeof(FCurve *), fcurve_cmp_for_cache); @@ -83,7 +82,7 @@ FCurvePathCache *BKE_fcurve_pathcache_create(ListBase *list) /* May over reserve, harmless. */ GHash *span_from_rna_path = BLI_ghash_str_new_ex(__func__, fcurve_array_len); uint span_index = 0; - i = 0; + uint i = 0; while (i < fcurve_array_len) { uint i_end; for (i_end = i + 1; i_end < fcurve_array_len; i_end++) {