From 6ebf244aced249366a4215787f768fde99523069 Mon Sep 17 00:00:00 2001 From: Joshua Leung Date: Tue, 5 Dec 2017 17:16:05 +1300 Subject: Added BKE_fcurves_main_cb(), a wrapper around BKE_animdata_main_cb to make it easier to apply fixes to all F-Curves in a file --- source/blender/blenkernel/BKE_animsys.h | 8 +++- source/blender/blenkernel/intern/anim_sys.c | 68 +++++++++++++++++++++++++++++ 2 files changed, 75 insertions(+), 1 deletion(-) (limited to 'source/blender') diff --git a/source/blender/blenkernel/BKE_animsys.h b/source/blender/blenkernel/BKE_animsys.h index 534a57765f6..5a9eeb38bc8 100644 --- a/source/blender/blenkernel/BKE_animsys.h +++ b/source/blender/blenkernel/BKE_animsys.h @@ -152,9 +152,15 @@ char *BKE_animdata_driver_path_hack(struct bContext *C, struct PointerRNA *ptr, /* Define for callback looper used in BKE_animdata_main_cb */ typedef void (*ID_AnimData_Edit_Callback)(struct ID *id, struct AnimData *adt, void *user_data); +/* Define for callback looper used in BKE_fcurves_main_cb */ +typedef void (*ID_FCurve_Edit_Callback)(struct ID *id, struct FCurve *fcu, void *user_data); + /* Loop over all datablocks applying callback */ -void BKE_animdata_main_cb(struct Main *main, ID_AnimData_Edit_Callback func, void *user_data); +void BKE_animdata_main_cb(struct Main *bmain, ID_AnimData_Edit_Callback func, void *user_data); + +/* Loop over all datablocks applying callback to all its F-Curves */ +void BKE_fcurves_main_cb(struct Main *bmain, ID_FCurve_Edit_Callback func, void *user_data); /* ************************************* */ // TODO: overrides, remapping, and path-finding api's diff --git a/source/blender/blenkernel/intern/anim_sys.c b/source/blender/blenkernel/intern/anim_sys.c index 2e0496b61d7..5aa13cad61d 100644 --- a/source/blender/blenkernel/intern/anim_sys.c +++ b/source/blender/blenkernel/intern/anim_sys.c @@ -1011,6 +1011,74 @@ void BKE_animdata_fix_paths_remove(ID *id, const char *prefix) } } + +/* Apply Op to All FCurves in Database --------------------------- */ + +/* "User-Data" wrapper used by BKE_fcurves_main_cb() */ +typedef struct AllFCurvesCbWrapper { + ID_FCurve_Edit_Callback func; /* Operation to apply on F-Curve */ + void *user_data; /* Custom data for that operation */ +} AllFCurvesCbWrapper; + +/* Helper for adt_apply_all_fcurves_cb() - Apply wrapped operator to list of F-Curves */ +static void fcurves_apply_cb(ID *id, ListBase *fcurves, ID_FCurve_Edit_Callback func, void *user_data) +{ + FCurve *fcu; + + for (fcu = fcurves->first; fcu; fcu = fcu->next) { + func(id, fcu, user_data); + } +} + +/* Helper for adt_apply_all_fcurves_cb() - Recursively go through each NLA strip */ +static void nlastrips_apply_all_curves_cb(ID *id, ListBase *strips, AllFCurvesCbWrapper *wrapper) +{ + NlaStrip *strip; + + for (strip = strips->first; strip; strip = strip->next) { + /* fix strip's action */ + if (strip->act) { + fcurves_apply_cb(id, &strip->act->curves, wrapper->func, wrapper->user_data); + } + + /* check sub-strips (if metas) */ + nlastrips_apply_all_curves_cb(id, &strip->strips, wrapper); + } +} + +/* Helper for BKE_fcurves_main_cb() - Dispatch wrapped operator to all F-Curves */ +static void adt_apply_all_fcurves_cb(ID *id, AnimData *adt, AllFCurvesCbWrapper *wrapper) +{ + NlaTrack *nlt; + + if (adt->action) { + fcurves_apply_cb(id, &adt->action->curves, wrapper->func, wrapper->user_data); + } + + if (adt->tmpact) { + fcurves_apply_cb(id, &adt->tmpact->curves, wrapper->func, wrapper->user_data); + } + + /* free drivers - stored as a list of F-Curves */ + fcurves_apply_cb(id, &adt->drivers, wrapper->func, wrapper->user_data); + + /* NLA Data - Animation Data for Strips */ + for (nlt = adt->nla_tracks.first; nlt; nlt = nlt->next) { + nlastrips_apply_all_curves_cb(id, &nlt->strips, wrapper); + } +} + +/* apply the given callback function on all F-Curves attached to data in main database */ +void BKE_fcurves_main_cb(Main *mainptr, ID_FCurve_Edit_Callback func, void *user_data) +{ + /* Wrap F-Curve operation stuff to pass to the general AnimData-level func */ + AllFCurvesCbWrapper wrapper = {func, user_data}; + + /* Use the AnimData-based function so that we don't have to reimplement all that stuff */ + BKE_animdata_main_cb(mainptr, adt_apply_all_fcurves_cb, &wrapper); +} + + /* Whole Database Ops -------------------------------------------- */ /* apply the given callback function on all data in main database */ -- cgit v1.2.3