Refactor: convert ListBase of tRKS_DSource to Vector

No functional changes

The keying set code was passing around a list
of `tRKS_DSource` through a lot of functions.
It turns it this was just a ListBase wrapper around `PointerRNA`.

So to make it clearer what is passed around, I replaced the
`ListBase` with a `Vector<PointerRNA>`

To make the use of `ANIM_relative_keyingset_add_source` clearer
I made two functions out of it with different parameters.
Those can take the vector as a reference and
EITHER only an `ID *`
OR an `ID *`, `StructRNA *` and a `void *`

Pull Request: https://projects.blender.org/blender/blender/pulls/113675
This commit is contained in:
Christoph Lendenfeld
2023-10-13 15:06:53 +02:00
committed by Christoph Lendenfeld
parent cb7668e64e
commit b753ef73a0
8 changed files with 71 additions and 94 deletions

View File

@@ -101,7 +101,6 @@ void autokeyframe_object(
ReportList *reports = CTX_wm_reports(C);
KeyingSet *active_ks = ANIM_scene_get_active_keyingset(scene);
ListBase dsources = {nullptr, nullptr};
Depsgraph *depsgraph = CTX_data_depsgraph_pointer(C);
const AnimationEvalContext anim_eval_context = BKE_animsys_eval_context_construct(
depsgraph, BKE_scene_frame_get(scene));
@@ -111,7 +110,8 @@ void autokeyframe_object(
flag = ANIM_get_keyframing_flags(scene, true);
/* Add data-source override for the object. */
ANIM_relative_keyingset_add_source(&dsources, id, nullptr, nullptr);
blender::Vector<PointerRNA> sources;
ANIM_relative_keyingset_add_source(sources, id);
if (is_autokey_flag(scene, AUTOKEY_FLAG_ONLYKEYINGSET) && (active_ks)) {
/* Only insert into active keyingset
@@ -119,7 +119,7 @@ void autokeyframe_object(
* does not need to have its iterator overridden.
*/
ANIM_apply_keyingset(
C, &dsources, active_ks, MODIFYKEY_MODE_INSERT, anim_eval_context.eval_time);
C, &sources, active_ks, MODIFYKEY_MODE_INSERT, anim_eval_context.eval_time);
}
else if (is_autokey_flag(scene, AUTOKEY_FLAG_INSERTAVAIL)) {
AnimData *adt = ob->adt;
@@ -187,25 +187,22 @@ void autokeyframe_object(
/* insert keyframes for the affected sets of channels using the builtin KeyingSets found */
if (do_loc) {
KeyingSet *ks = ANIM_builtin_keyingset_get_named(nullptr, ANIM_KS_LOCATION_ID);
ANIM_apply_keyingset(C, &dsources, ks, MODIFYKEY_MODE_INSERT, anim_eval_context.eval_time);
ANIM_apply_keyingset(C, &sources, ks, MODIFYKEY_MODE_INSERT, anim_eval_context.eval_time);
}
if (do_rot) {
KeyingSet *ks = ANIM_builtin_keyingset_get_named(nullptr, ANIM_KS_ROTATION_ID);
ANIM_apply_keyingset(C, &dsources, ks, MODIFYKEY_MODE_INSERT, anim_eval_context.eval_time);
ANIM_apply_keyingset(C, &sources, ks, MODIFYKEY_MODE_INSERT, anim_eval_context.eval_time);
}
if (do_scale) {
KeyingSet *ks = ANIM_builtin_keyingset_get_named(nullptr, ANIM_KS_SCALING_ID);
ANIM_apply_keyingset(C, &dsources, ks, MODIFYKEY_MODE_INSERT, anim_eval_context.eval_time);
ANIM_apply_keyingset(C, &sources, ks, MODIFYKEY_MODE_INSERT, anim_eval_context.eval_time);
}
}
/* insert keyframe in all (transform) channels */
else {
KeyingSet *ks = ANIM_builtin_keyingset_get_named(nullptr, ANIM_KS_LOC_ROT_SCALE_ID);
ANIM_apply_keyingset(C, &dsources, ks, MODIFYKEY_MODE_INSERT, anim_eval_context.eval_time);
ANIM_apply_keyingset(C, &sources, ks, MODIFYKEY_MODE_INSERT, anim_eval_context.eval_time);
}
/* free temp info */
BLI_freelistN(&dsources);
}
bool autokeyframe_object(bContext *C, Scene *scene, Object *ob, KeyingSet *ks)
@@ -215,16 +212,14 @@ bool autokeyframe_object(bContext *C, Scene *scene, Object *ob, KeyingSet *ks)
return false;
}
ListBase dsources = {nullptr, nullptr};
/* Now insert the key-frame(s) using the Keying Set:
* 1) Add data-source override for the Object.
* 2) Insert key-frames.
* 3) Free the extra info.
*/
ANIM_relative_keyingset_add_source(&dsources, &ob->id, nullptr, nullptr);
ANIM_apply_keyingset(C, &dsources, ks, MODIFYKEY_MODE_INSERT, BKE_scene_frame_get(scene));
BLI_freelistN(&dsources);
blender::Vector<PointerRNA> sources;
ANIM_relative_keyingset_add_source(sources, &ob->id);
ANIM_apply_keyingset(C, &sources, ks, MODIFYKEY_MODE_INSERT, BKE_scene_frame_get(scene));
return true;
}
@@ -234,16 +229,15 @@ bool autokeyframe_pchan(bContext *C, Scene *scene, Object *ob, bPoseChannel *pch
if (autokeyframe_cfra_can_key(scene, &ob->id)) {
return false;
}
ListBase dsources = {nullptr, nullptr};
/* Now insert the keyframe(s) using the Keying Set:
* 1) Add data-source override for the pose-channel.
* 2) Insert key-frames.
* 3) Free the extra info.
*/
ANIM_relative_keyingset_add_source(&dsources, &ob->id, &RNA_PoseBone, pchan);
ANIM_apply_keyingset(C, &dsources, ks, MODIFYKEY_MODE_INSERT, BKE_scene_frame_get(scene));
BLI_freelistN(&dsources);
blender::Vector<PointerRNA> sources;
ANIM_relative_keyingset_add_source(sources, &ob->id, &RNA_PoseBone, pchan);
ANIM_apply_keyingset(C, &sources, ks, MODIFYKEY_MODE_INSERT, BKE_scene_frame_get(scene));
return true;
}

View File

@@ -904,15 +904,6 @@ bool ANIM_keyingset_context_ok_poll(bContext *C, KeyingSet *ks)
/* Special 'Overrides' Iterator for Relative KeyingSets ------ */
/* 'Data Sources' for relative Keying Set 'overrides'
* - this is basically a wrapper for PointerRNA's in a linked list
* - do not allow this to be accessed from outside for now
*/
struct tRKS_DSource {
tRKS_DSource *next, *prev;
PointerRNA ptr; /* the whole point of this exercise! */
};
/* Iterator used for overriding the behavior of iterators defined for
* relative Keying Sets, with the main usage of this being operators
* requiring Auto Keyframing. Internal Use Only!
@@ -920,45 +911,38 @@ struct tRKS_DSource {
static void RKS_ITER_overrides_list(KeyingSetInfo *ksi,
bContext *C,
KeyingSet *ks,
ListBase *dsources)
blender::Vector<PointerRNA> &sources)
{
LISTBASE_FOREACH (tRKS_DSource *, ds, dsources) {
/* run generate callback on this data */
ksi->generate(ksi, C, ks, &ds->ptr);
for (PointerRNA ptr : sources) {
/* Run generate callback on this data. */
ksi->generate(ksi, C, ks, &ptr);
}
}
void ANIM_relative_keyingset_add_source(ListBase *dsources, ID *id, StructRNA *srna, void *data)
void ANIM_relative_keyingset_add_source(blender::Vector<PointerRNA> &sources,
ID *id,
StructRNA *srna,
void *data)
{
tRKS_DSource *ds;
/* sanity checks
* - we must have somewhere to output the data
* - we must have both srna+data (and with id too optionally), or id by itself only
*/
if (dsources == nullptr) {
if (ELEM(nullptr, srna, data, id)) {
return;
}
if (ELEM(nullptr, srna, data) && (id == nullptr)) {
sources.append(RNA_pointer_create(id, srna, data));
}
void ANIM_relative_keyingset_add_source(blender::Vector<PointerRNA> &sources, ID *id)
{
if (id == nullptr) {
return;
}
/* allocate new elem, and add to the list */
ds = static_cast<tRKS_DSource *>(MEM_callocN(sizeof(tRKS_DSource), "tRKS_DSource"));
BLI_addtail(dsources, ds);
/* depending on what data we have, create using ID or full pointer call */
if (srna && data) {
ds->ptr = RNA_pointer_create(id, srna, data);
}
else {
ds->ptr = RNA_id_pointer_create(id);
}
sources.append(RNA_id_pointer_create(id));
}
/* KeyingSet Operations (Insert/Delete Keyframes) ------------ */
eModifyKey_Returns ANIM_validate_keyingset(bContext *C, ListBase *dsources, KeyingSet *ks)
eModifyKey_Returns ANIM_validate_keyingset(bContext *C,
blender::Vector<PointerRNA> *sources,
KeyingSet *ks)
{
/* sanity check */
if (ks == nullptr) {
@@ -994,8 +978,8 @@ eModifyKey_Returns ANIM_validate_keyingset(bContext *C, ListBase *dsources, Keyi
/* if a list of data sources are provided, run a special iterator over them,
* otherwise, just continue per normal
*/
if (dsources) {
RKS_ITER_overrides_list(ksi, C, ks, dsources);
if (sources != nullptr) {
RKS_ITER_overrides_list(ksi, C, ks, *sources);
}
else {
ksi->iter(ksi, C, ks);
@@ -1044,7 +1028,8 @@ static eInsertKeyFlags keyingset_apply_keying_flags(const eInsertKeyFlags base_f
return result;
}
int ANIM_apply_keyingset(bContext *C, ListBase *dsources, KeyingSet *ks, short mode, float cfra)
int ANIM_apply_keyingset(
bContext *C, blender::Vector<PointerRNA> *sources, KeyingSet *ks, short mode, float cfra)
{
/* sanity checks */
if (ks == nullptr) {
@@ -1066,7 +1051,7 @@ int ANIM_apply_keyingset(bContext *C, ListBase *dsources, KeyingSet *ks, short m
/* if relative Keying Sets, poll and build up the paths */
{
const eModifyKey_Returns error = ANIM_validate_keyingset(C, dsources, ks);
const eModifyKey_Returns error = ANIM_validate_keyingset(C, sources, ks);
if (error != MODIFYKEY_SUCCESS) {
BLI_assert(error < 0);
/* return error code if failed */

View File

@@ -133,7 +133,7 @@ static void poselib_keytag_pose(bContext *C, Scene *scene, PoseBlendData *pbd)
bAction *act = poselib_action_to_blend(pbd);
KeyingSet *ks = ANIM_get_keyingset_for_autokeying(scene, ANIM_KS_WHOLE_CHARACTER_ID);
ListBase dsources = {nullptr, nullptr};
blender::Vector<PointerRNA> sources;
/* start tagging/keying */
const bArmature *armature = static_cast<const bArmature *>(pbd->ob->data);
@@ -151,12 +151,11 @@ static void poselib_keytag_pose(bContext *C, Scene *scene, PoseBlendData *pbd)
}
/* Add data-source override for the PoseChannel, to be used later. */
ANIM_relative_keyingset_add_source(&dsources, &pbd->ob->id, &RNA_PoseBone, pchan);
ANIM_relative_keyingset_add_source(sources, &pbd->ob->id, &RNA_PoseBone, pchan);
}
/* Perform actual auto-keying. */
ANIM_apply_keyingset(C, &dsources, ks, MODIFYKEY_MODE_INSERT, float(scene->r.cfra));
BLI_freelistN(&dsources);
ANIM_apply_keyingset(C, &sources, ks, MODIFYKEY_MODE_INSERT, float(scene->r.cfra));
/* send notifiers for this */
WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_EDITED, nullptr);

View File

@@ -1198,7 +1198,7 @@ static int pose_clear_transform_generic_exec(bContext *C,
FOREACH_OBJECT_IN_MODE_BEGIN (scene, view_layer, v3d, OB_ARMATURE, OB_MODE_POSE, ob_iter) {
/* XXX: UGLY HACK (for auto-key + clear transforms). */
Object *ob_eval = DEG_get_evaluated_object(depsgraph, ob_iter);
ListBase dsources = {nullptr, nullptr};
blender::Vector<PointerRNA> sources;
bool changed = false;
FOREACH_PCHAN_SELECTED_IN_OBJECT_BEGIN (ob_iter, pchan) {
@@ -1209,7 +1209,7 @@ static int pose_clear_transform_generic_exec(bContext *C,
/* do auto-keyframing as appropriate */
if (blender::animrig::autokeyframe_cfra_can_key(scene, &ob_iter->id)) {
/* tag for autokeying later */
ANIM_relative_keyingset_add_source(&dsources, &ob_iter->id, &RNA_PoseBone, pchan);
ANIM_relative_keyingset_add_source(sources, &ob_iter->id, &RNA_PoseBone, pchan);
#if 1 /* XXX: Ugly Hack - Run clearing function on evaluated copy of pchan */
bPoseChannel *pchan_eval = BKE_pose_channel_find_name(ob_eval->pose, pchan->name);
@@ -1223,19 +1223,17 @@ static int pose_clear_transform_generic_exec(bContext *C,
changed_multi = true;
/* perform autokeying on the bones if needed */
if (!BLI_listbase_is_empty(&dsources)) {
if (!sources.is_empty()) {
/* get KeyingSet to use */
KeyingSet *ks = ANIM_get_keyingset_for_autokeying(scene, default_ksName);
/* insert keyframes */
ANIM_apply_keyingset(C, &dsources, ks, MODIFYKEY_MODE_INSERT, float(scene->r.cfra));
ANIM_apply_keyingset(C, &sources, ks, MODIFYKEY_MODE_INSERT, float(scene->r.cfra));
/* now recalculate paths */
if (ob_iter->pose->avs.path_bakeflag & MOTIONPATH_BAKE_HAS_PATHS) {
ED_pose_recalculate_paths(C, scene, ob_iter, POSE_PATH_CALC_RANGE_FULL);
}
BLI_freelistN(&dsources);
}
DEG_id_tag_update(&ob_iter->id, ID_RECALC_GEOMETRY);

View File

@@ -276,7 +276,7 @@ void poseAnim_mapping_autoKeyframe(bContext *C, Scene *scene, ListBase *pfLinks,
/* Insert keyframes as necessary if auto-key-framing. */
KeyingSet *ks = ANIM_get_keyingset_for_autokeying(scene, ANIM_KS_WHOLE_CHARACTER_ID);
ListBase dsources = {nullptr, nullptr};
blender::Vector<PointerRNA> sources;
/* iterate over each pose-channel affected, tagging bones to be keyed */
/* XXX: here we already have the information about what transforms exist, though
@@ -290,12 +290,11 @@ void poseAnim_mapping_autoKeyframe(bContext *C, Scene *scene, ListBase *pfLinks,
}
/* Add data-source override for the PoseChannel, to be used later. */
ANIM_relative_keyingset_add_source(&dsources, &pfl->ob->id, &RNA_PoseBone, pchan);
ANIM_relative_keyingset_add_source(sources, &pfl->ob->id, &RNA_PoseBone, pchan);
}
/* insert keyframes for all relevant bones in one go */
ANIM_apply_keyingset(C, &dsources, ks, MODIFYKEY_MODE_INSERT, cframe);
BLI_freelistN(&dsources);
ANIM_apply_keyingset(C, &sources, ks, MODIFYKEY_MODE_INSERT, cframe);
/* do the bone paths
* - only do this if keyframes should have been added

View File

@@ -8,6 +8,7 @@
#pragma once
#include "BLI_vector.hh"
#include "DNA_anim_types.h"
#include "RNA_types.hh"
@@ -185,7 +186,11 @@ struct KeyingSetInfo {
/**
* Add another data source for Relative Keying Sets to be evaluated with.
*/
void ANIM_relative_keyingset_add_source(ListBase *dsources, ID *id, StructRNA *srna, void *data);
void ANIM_relative_keyingset_add_source(blender::Vector<PointerRNA> &sources,
ID *id,
StructRNA *srna,
void *data);
void ANIM_relative_keyingset_add_source(blender::Vector<PointerRNA> &sources, ID *id);
/* mode for modify_keyframes */
enum eModifyKey_Modes {
@@ -208,9 +213,13 @@ enum eModifyKey_Returns {
* where their list of paths is dynamically generated based on the
* current context info.
*
* \note Passing sources as pointer because it can be a nullptr.
*
* \return 0 if succeeded, otherwise an error code: #eModifyKey_Returns.
*/
eModifyKey_Returns ANIM_validate_keyingset(bContext *C, ListBase *dsources, KeyingSet *ks);
eModifyKey_Returns ANIM_validate_keyingset(bContext *C,
blender::Vector<PointerRNA> *sources,
KeyingSet *ks);
/**
* Use the specified #KeyingSet and context info (if required)
@@ -222,7 +231,8 @@ eModifyKey_Returns ANIM_validate_keyingset(bContext *C, ListBase *dsources, Keyi
* \returns the number of channels that key-frames were added or
* an #eModifyKey_Returns value (always a negative number).
*/
int ANIM_apply_keyingset(bContext *C, ListBase *dsources, KeyingSet *ks, short mode, float cfra);
int ANIM_apply_keyingset(
bContext *C, blender::Vector<PointerRNA> *sources, KeyingSet *ks, short mode, float cfra);
/* -------- */

View File

@@ -642,10 +642,9 @@ bool ED_view3d_camera_autokey(
{
if (blender::animrig::autokeyframe_cfra_can_key(scene, id_key)) {
const float cfra = float(scene->r.cfra);
ListBase dsources = {nullptr, nullptr};
blender::Vector<PointerRNA> sources;
/* add data-source override for the camera object */
ANIM_relative_keyingset_add_source(&dsources, id_key, nullptr, nullptr);
ANIM_relative_keyingset_add_source(sources, id_key);
/* insert keyframes
* 1) on the first frame
@@ -654,16 +653,13 @@ bool ED_view3d_camera_autokey(
*/
if (do_rotate) {
KeyingSet *ks = ANIM_get_keyingset_for_autokeying(scene, ANIM_KS_ROTATION_ID);
ANIM_apply_keyingset(C, &dsources, ks, MODIFYKEY_MODE_INSERT, cfra);
ANIM_apply_keyingset(C, &sources, ks, MODIFYKEY_MODE_INSERT, cfra);
}
if (do_translate) {
KeyingSet *ks = ANIM_get_keyingset_for_autokeying(scene, ANIM_KS_LOCATION_ID);
ANIM_apply_keyingset(C, &dsources, ks, MODIFYKEY_MODE_INSERT, cfra);
ANIM_apply_keyingset(C, &sources, ks, MODIFYKEY_MODE_INSERT, cfra);
}
/* free temp data */
BLI_freelistN(&dsources);
return true;
}
return false;

View File

@@ -121,16 +121,15 @@ static void autokeyframe_pose(
continue;
}
ListBase dsources = {nullptr, nullptr};
blender::Vector<PointerRNA> sources;
/* Add data-source override for the camera object. */
ANIM_relative_keyingset_add_source(&dsources, id, &RNA_PoseBone, pchan);
ANIM_relative_keyingset_add_source(sources, id, &RNA_PoseBone, pchan);
/* only insert into active keyingset? */
if (blender::animrig::is_autokey_flag(scene, AUTOKEY_FLAG_ONLYKEYINGSET) && (active_ks)) {
/* Run the active Keying Set on the current data-source. */
ANIM_apply_keyingset(
C, &dsources, active_ks, MODIFYKEY_MODE_INSERT, anim_eval_context.eval_time);
C, &sources, active_ks, MODIFYKEY_MODE_INSERT, anim_eval_context.eval_time);
}
/* only insert into available channels? */
else if (blender::animrig::is_autokey_flag(scene, AUTOKEY_FLAG_INSERTAVAIL)) {
@@ -198,25 +197,22 @@ static void autokeyframe_pose(
if (do_loc) {
KeyingSet *ks = ANIM_builtin_keyingset_get_named(nullptr, ANIM_KS_LOCATION_ID);
ANIM_apply_keyingset(C, &dsources, ks, MODIFYKEY_MODE_INSERT, anim_eval_context.eval_time);
ANIM_apply_keyingset(C, &sources, ks, MODIFYKEY_MODE_INSERT, anim_eval_context.eval_time);
}
if (do_rot) {
KeyingSet *ks = ANIM_builtin_keyingset_get_named(nullptr, ANIM_KS_ROTATION_ID);
ANIM_apply_keyingset(C, &dsources, ks, MODIFYKEY_MODE_INSERT, anim_eval_context.eval_time);
ANIM_apply_keyingset(C, &sources, ks, MODIFYKEY_MODE_INSERT, anim_eval_context.eval_time);
}
if (do_scale) {
KeyingSet *ks = ANIM_builtin_keyingset_get_named(nullptr, ANIM_KS_SCALING_ID);
ANIM_apply_keyingset(C, &dsources, ks, MODIFYKEY_MODE_INSERT, anim_eval_context.eval_time);
ANIM_apply_keyingset(C, &sources, ks, MODIFYKEY_MODE_INSERT, anim_eval_context.eval_time);
}
}
/* insert keyframe in all (transform) channels */
else {
KeyingSet *ks = ANIM_builtin_keyingset_get_named(nullptr, ANIM_KS_LOC_ROT_SCALE_ID);
ANIM_apply_keyingset(C, &dsources, ks, MODIFYKEY_MODE_INSERT, anim_eval_context.eval_time);
ANIM_apply_keyingset(C, &sources, ks, MODIFYKEY_MODE_INSERT, anim_eval_context.eval_time);
}
/* free temp info */
BLI_freelistN(&dsources);
}
BKE_animsys_free_nla_keyframing_context_cache(&nla_cache);