Cleanup: style, use braces for blenkernel
[blender.git] / source / blender / blenkernel / intern / anim_sys.c
index 1b09868..e8bcb66 100644 (file)
@@ -21,7 +21,6 @@
  * \ingroup bke
  */
 
-
 #include <stdio.h>
 #include <string.h>
 #include <stddef.h>
@@ -42,7 +41,7 @@
 #include "BLT_translation.h"
 
 #include "DNA_anim_types.h"
-#include "DNA_lamp_types.h"
+#include "DNA_light_types.h"
 #include "DNA_material_types.h"
 #include "DNA_object_types.h"
 #include "DNA_scene_types.h"
@@ -84,39 +83,48 @@ static CLG_LogRef LOG = {"bke.anim_sys"};
 /* Check if ID can have AnimData */
 bool id_type_can_have_animdata(const short id_type)
 {
-       /* Only some ID-blocks have this info for now */
-       /* TODO: finish adding this for the other blocktypes */
-       switch (id_type) {
-               /* has AnimData */
-               case ID_OB:
-               case ID_ME: case ID_MB: case ID_CU: case ID_AR: case ID_LT:
-               case ID_KE:
-               case ID_PA:
-               case ID_MA: case ID_TE: case ID_NT:
-               case ID_LA: case ID_CA: case ID_WO:
-               case ID_LS:
-               case ID_LP:
-               case ID_SPK:
-               case ID_SCE:
-               case ID_MC:
-               case ID_MSK:
-               case ID_GD:
-               case ID_CF:
-                       return true;
-
-               /* no AnimData */
-               default:
-                       return false;
-       }
+  /* Only some ID-blocks have this info for now */
+  /* TODO: finish adding this for the other blocktypes */
+  switch (id_type) {
+    /* has AnimData */
+    case ID_OB:
+    case ID_ME:
+    case ID_MB:
+    case ID_CU:
+    case ID_AR:
+    case ID_LT:
+    case ID_KE:
+    case ID_PA:
+    case ID_MA:
+    case ID_TE:
+    case ID_NT:
+    case ID_LA:
+    case ID_CA:
+    case ID_WO:
+    case ID_LS:
+    case ID_LP:
+    case ID_SPK:
+    case ID_SCE:
+    case ID_MC:
+    case ID_MSK:
+    case ID_GD:
+    case ID_CF:
+      return true;
+
+    /* no AnimData */
+    default:
+      return false;
+  }
 }
 
 bool id_can_have_animdata(const ID *id)
 {
-       /* sanity check */
-       if (id == NULL)
-               return false;
+  /* sanity check */
+  if (id == NULL) {
+    return false;
+  }
 
-       return id_type_can_have_animdata(GS(id->name));
+  return id_type_can_have_animdata(GS(id->name));
 }
 
 /* Get AnimData from the given ID-block. In order for this to work, we assume that
@@ -125,16 +133,17 @@ bool id_can_have_animdata(const ID *id)
  */
 AnimData *BKE_animdata_from_id(ID *id)
 {
-       /* only some ID-blocks have this info for now, so we cast the
-        * types that do to be of type IdAdtTemplate, and extract the
-        * AnimData that way
-        */
-       if (id_can_have_animdata(id)) {
-               IdAdtTemplate *iat = (IdAdtTemplate *)id;
-               return iat->adt;
-       }
-       else
-               return NULL;
+  /* only some ID-blocks have this info for now, so we cast the
+   * types that do to be of type IdAdtTemplate, and extract the
+   * AnimData that way
+   */
+  if (id_can_have_animdata(id)) {
+    IdAdtTemplate *iat = (IdAdtTemplate *)id;
+    return iat->adt;
+  }
+  else {
+    return NULL;
+  }
 }
 
 /* Add AnimData to the given ID-block. In order for this to work, we assume that
@@ -143,28 +152,29 @@ AnimData *BKE_animdata_from_id(ID *id)
  */
 AnimData *BKE_animdata_add_id(ID *id)
 {
-       /* Only some ID-blocks have this info for now, so we cast the
-        * types that do to be of type IdAdtTemplate, and add the AnimData
-        * to it using the template
-        */
-       if (id_can_have_animdata(id)) {
-               IdAdtTemplate *iat = (IdAdtTemplate *)id;
+  /* Only some ID-blocks have this info for now, so we cast the
+   * types that do to be of type IdAdtTemplate, and add the AnimData
+   * to it using the template
+   */
+  if (id_can_have_animdata(id)) {
+    IdAdtTemplate *iat = (IdAdtTemplate *)id;
 
-               /* check if there's already AnimData, in which case, don't add */
-               if (iat->adt == NULL) {
-                       AnimData *adt;
+    /* check if there's already AnimData, in which case, don't add */
+    if (iat->adt == NULL) {
+      AnimData *adt;
 
-                       /* add animdata */
-                       adt = iat->adt = MEM_callocN(sizeof(AnimData), "AnimData");
+      /* add animdata */
+      adt = iat->adt = MEM_callocN(sizeof(AnimData), "AnimData");
 
-                       /* set default settings */
-                       adt->act_influence = 1.0f;
-               }
+      /* set default settings */
+      adt->act_influence = 1.0f;
+    }
 
-               return iat->adt;
-       }
-       else
-               return NULL;
+    return iat->adt;
+  }
+  else {
+    return NULL;
+  }
 }
 
 /* Action Setter --------------------------------------- */
@@ -172,52 +182,57 @@ AnimData *BKE_animdata_add_id(ID *id)
 /* Called when user tries to change the active action of an AnimData block (via RNA, Outliner, etc.) */
 bool BKE_animdata_set_action(ReportList *reports, ID *id, bAction *act)
 {
-       AnimData *adt = BKE_animdata_from_id(id);
-       bool ok = false;
-
-       /* animdata validity check */
-       if (adt == NULL) {
-               BKE_report(reports, RPT_WARNING, "No AnimData to set action on");
-               return ok;
-       }
-
-       /* active action is only editable when it is not a tweaking strip
-        * see rna_AnimData_action_editable() in rna_animation.c
-        */
-       if ((adt->flag & ADT_NLA_EDIT_ON) || (adt->actstrip) || (adt->tmpact)) {
-               /* cannot remove, otherwise things turn to custard */
-               BKE_report(reports, RPT_ERROR, "Cannot change action, as it is still being edited in NLA");
-               return ok;
-       }
-
-       /* manage usercount for current action */
-       if (adt->action)
-               id_us_min((ID *)adt->action);
-
-       /* assume that AnimData's action can in fact be edited... */
-       if (act) {
-               /* action must have same type as owner */
-               if (ELEM(act->idroot, 0, GS(id->name))) {
-                       /* can set */
-                       adt->action = act;
-                       id_us_plus((ID *)adt->action);
-                       ok = true;
-               }
-               else {
-                       /* cannot set */
-                       BKE_reportf(reports, RPT_ERROR,
-                                   "Could not set action '%s' onto ID '%s', as it does not have suitably rooted paths "
-                                   "for this purpose", act->id.name + 2, id->name);
-                       /* ok = false; */
-               }
-       }
-       else {
-               /* just clearing the action... */
-               adt->action = NULL;
-               ok = true;
-       }
-
-       return ok;
+  AnimData *adt = BKE_animdata_from_id(id);
+  bool ok = false;
+
+  /* animdata validity check */
+  if (adt == NULL) {
+    BKE_report(reports, RPT_WARNING, "No AnimData to set action on");
+    return ok;
+  }
+
+  /* active action is only editable when it is not a tweaking strip
+   * see rna_AnimData_action_editable() in rna_animation.c
+   */
+  if ((adt->flag & ADT_NLA_EDIT_ON) || (adt->actstrip) || (adt->tmpact)) {
+    /* cannot remove, otherwise things turn to custard */
+    BKE_report(reports, RPT_ERROR, "Cannot change action, as it is still being edited in NLA");
+    return ok;
+  }
+
+  /* manage usercount for current action */
+  if (adt->action) {
+    id_us_min((ID *)adt->action);
+  }
+
+  /* assume that AnimData's action can in fact be edited... */
+  if (act) {
+    /* action must have same type as owner */
+    if (ELEM(act->idroot, 0, GS(id->name))) {
+      /* can set */
+      adt->action = act;
+      id_us_plus((ID *)adt->action);
+      ok = true;
+    }
+    else {
+      /* cannot set */
+      BKE_reportf(
+          reports,
+          RPT_ERROR,
+          "Could not set action '%s' onto ID '%s', as it does not have suitably rooted paths "
+          "for this purpose",
+          act->id.name + 2,
+          id->name);
+      /* ok = false; */
+    }
+  }
+  else {
+    /* just clearing the action... */
+    adt->action = NULL;
+    ok = true;
+  }
+
+  return ok;
 }
 
 /* Freeing -------------------------------------------- */
@@ -225,41 +240,43 @@ bool BKE_animdata_set_action(ReportList *reports, ID *id, bAction *act)
 /* Free AnimData used by the nominated ID-block, and clear ID-block's AnimData pointer */
 void BKE_animdata_free(ID *id, const bool do_id_user)
 {
-       /* Only some ID-blocks have this info for now, so we cast the
-        * types that do to be of type IdAdtTemplate
-        */
-       if (id_can_have_animdata(id)) {
-               IdAdtTemplate *iat = (IdAdtTemplate *)id;
-               AnimData *adt = iat->adt;
-
-               /* check if there's any AnimData to start with */
-               if (adt) {
-                       if (do_id_user) {
-                               /* unlink action (don't free, as it's in its own list) */
-                               if (adt->action)
-                                       id_us_min(&adt->action->id);
-                               /* same goes for the temporarily displaced action */
-                               if (adt->tmpact)
-                                       id_us_min(&adt->tmpact->id);
-                       }
-
-                       /* free nla data */
-                       BKE_nla_tracks_free(&adt->nla_tracks, do_id_user);
-
-                       /* free drivers - stored as a list of F-Curves */
-                       free_fcurves(&adt->drivers);
-
-                       /* free driver array cache */
-                       MEM_SAFE_FREE(adt->driver_array);
-
-                       /* free overrides */
-                       /* TODO... */
-
-                       /* free animdata now */
-                       MEM_freeN(adt);
-                       iat->adt = NULL;
-               }
-       }
+  /* Only some ID-blocks have this info for now, so we cast the
+   * types that do to be of type IdAdtTemplate
+   */
+  if (id_can_have_animdata(id)) {
+    IdAdtTemplate *iat = (IdAdtTemplate *)id;
+    AnimData *adt = iat->adt;
+
+    /* check if there's any AnimData to start with */
+    if (adt) {
+      if (do_id_user) {
+        /* unlink action (don't free, as it's in its own list) */
+        if (adt->action) {
+          id_us_min(&adt->action->id);
+        }
+        /* same goes for the temporarily displaced action */
+        if (adt->tmpact) {
+          id_us_min(&adt->tmpact->id);
+        }
+      }
+
+      /* free nla data */
+      BKE_nla_tracks_free(&adt->nla_tracks, do_id_user);
+
+      /* free drivers - stored as a list of F-Curves */
+      free_fcurves(&adt->drivers);
+
+      /* free driver array cache */
+      MEM_SAFE_FREE(adt->driver_array);
+
+      /* free overrides */
+      /* TODO... */
+
+      /* free animdata now */
+      MEM_freeN(adt);
+      iat->adt = NULL;
+    }
+  }
 }
 
 /* Copying -------------------------------------------- */
@@ -271,39 +288,40 @@ void BKE_animdata_free(ID *id, const bool do_id_user)
  */
 AnimData *BKE_animdata_copy(Main *bmain, AnimData *adt, const int flag)
 {
-       AnimData *dadt;
+  AnimData *dadt;
 
-       const bool do_action = (flag & LIB_ID_COPY_ACTIONS) != 0 && (flag & LIB_ID_CREATE_NO_MAIN) == 0;
-       const bool do_id_user = (flag & LIB_ID_CREATE_NO_USER_REFCOUNT) == 0;
+  const bool do_action = (flag & LIB_ID_COPY_ACTIONS) != 0 && (flag & LIB_ID_CREATE_NO_MAIN) == 0;
+  const bool do_id_user = (flag & LIB_ID_CREATE_NO_USER_REFCOUNT) == 0;
 
-       /* sanity check before duplicating struct */
-       if (adt == NULL)
-               return NULL;
-       dadt = MEM_dupallocN(adt);
+  /* sanity check before duplicating struct */
+  if (adt == NULL) {
+    return NULL;
+  }
+  dadt = MEM_dupallocN(adt);
 
-       /* make a copy of action - at worst, user has to delete copies... */
-       if (do_action) {
-               BLI_assert(bmain != NULL);
-               BKE_id_copy(bmain, (ID *)dadt->action, (ID **)&dadt->action);
-               BKE_id_copy(bmain, (ID *)dadt->tmpact, (ID **)&dadt->tmpact);
-       }
-       else if (do_id_user) {
-               id_us_plus((ID *)dadt->action);
-               id_us_plus((ID *)dadt->tmpact);
-       }
+  /* make a copy of action - at worst, user has to delete copies... */
+  if (do_action) {
+    BLI_assert(bmain != NULL);
+    BKE_id_copy(bmain, (ID *)dadt->action, (ID **)&dadt->action);
+    BKE_id_copy(bmain, (ID *)dadt->tmpact, (ID **)&dadt->tmpact);
+  }
+  else if (do_id_user) {
+    id_us_plus((ID *)dadt->action);
+    id_us_plus((ID *)dadt->tmpact);
+  }
 
-       /* duplicate NLA data */
-       BKE_nla_tracks_copy(bmain, &dadt->nla_tracks, &adt->nla_tracks, flag);
+  /* duplicate NLA data */
+  BKE_nla_tracks_copy(bmain, &dadt->nla_tracks, &adt->nla_tracks, flag);
 
-       /* duplicate drivers (F-Curves) */
-       copy_fcurves(&dadt->drivers, &adt->drivers);
-       dadt->driver_array = NULL;
+  /* duplicate drivers (F-Curves) */
+  copy_fcurves(&dadt->drivers, &adt->drivers);
+  dadt->driver_array = NULL;
 
-       /* don't copy overrides */
-       BLI_listbase_clear(&dadt->overrides);
+  /* don't copy overrides */
+  BLI_listbase_clear(&dadt->overrides);
 
-       /* return */
-       return dadt;
+  /* return */
+  return dadt;
 }
 
 /**
@@ -312,110 +330,112 @@ AnimData *BKE_animdata_copy(Main *bmain, AnimData *adt, const int flag)
  */
 bool BKE_animdata_copy_id(Main *bmain, ID *id_to, ID *id_from, const int flag)
 {
-       AnimData *adt;
+  AnimData *adt;
 
-       if ((id_to && id_from) && (GS(id_to->name) != GS(id_from->name)))
-               return false;
+  if ((id_to && id_from) && (GS(id_to->name) != GS(id_from->name))) {
+    return false;
+  }
 
-       BKE_animdata_free(id_to, (flag & LIB_ID_CREATE_NO_USER_REFCOUNT) == 0);
+  BKE_animdata_free(id_to, (flag & LIB_ID_CREATE_NO_USER_REFCOUNT) == 0);
 
-       adt = BKE_animdata_from_id(id_from);
-       if (adt) {
-               IdAdtTemplate *iat = (IdAdtTemplate *)id_to;
-               iat->adt = BKE_animdata_copy(bmain, adt, flag);
-       }
+  adt = BKE_animdata_from_id(id_from);
+  if (adt) {
+    IdAdtTemplate *iat = (IdAdtTemplate *)id_to;
+    iat->adt = BKE_animdata_copy(bmain, adt, flag);
+  }
 
-       return true;
+  return true;
 }
 
 void BKE_animdata_copy_id_action(Main *bmain, ID *id, const bool set_newid)
 {
-       AnimData *adt = BKE_animdata_from_id(id);
-       if (adt) {
-               if (adt->action) {
-                       id_us_min((ID *)adt->action);
-                       adt->action = set_newid ? ID_NEW_SET(adt->action, BKE_action_copy(bmain, adt->action)) :
-                                                 BKE_action_copy(bmain, adt->action);
-               }
-               if (adt->tmpact) {
-                       id_us_min((ID *)adt->tmpact);
-                       adt->tmpact = set_newid ? ID_NEW_SET(adt->tmpact, BKE_action_copy(bmain, adt->tmpact)) :
-                                                 BKE_action_copy(bmain, adt->tmpact);
-               }
-       }
+  AnimData *adt = BKE_animdata_from_id(id);
+  if (adt) {
+    if (adt->action) {
+      id_us_min((ID *)adt->action);
+      adt->action = set_newid ? ID_NEW_SET(adt->action, BKE_action_copy(bmain, adt->action)) :
+                                BKE_action_copy(bmain, adt->action);
+    }
+    if (adt->tmpact) {
+      id_us_min((ID *)adt->tmpact);
+      adt->tmpact = set_newid ? ID_NEW_SET(adt->tmpact, BKE_action_copy(bmain, adt->tmpact)) :
+                                BKE_action_copy(bmain, adt->tmpact);
+    }
+  }
 }
 
 /* Merge copies of the data from the src AnimData into the destination AnimData */
 void BKE_animdata_merge_copy(
-        Main *bmain, ID *dst_id, ID *src_id,
-        eAnimData_MergeCopy_Modes action_mode, bool fix_drivers)
-{
-       AnimData *src = BKE_animdata_from_id(src_id);
-       AnimData *dst = BKE_animdata_from_id(dst_id);
-
-       /* sanity checks */
-       if (ELEM(NULL, dst, src))
-               return;
-
-       // TODO: we must unset all "tweakmode" flags
-       if ((src->flag & ADT_NLA_EDIT_ON) || (dst->flag & ADT_NLA_EDIT_ON)) {
-               CLOG_ERROR(&LOG, "Merging AnimData blocks while editing NLA is dangerous as it may cause data corruption");
-               return;
-       }
-
-       /* handle actions... */
-       if (action_mode == ADT_MERGECOPY_SRC_COPY) {
-               /* make a copy of the actions */
-               dst->action = BKE_action_copy(bmain, src->action);
-               dst->tmpact = BKE_action_copy(bmain, src->tmpact);
-       }
-       else if (action_mode == ADT_MERGECOPY_SRC_REF) {
-               /* make a reference to it */
-               dst->action = src->action;
-               id_us_plus((ID *)dst->action);
-
-               dst->tmpact = src->tmpact;
-               id_us_plus((ID *)dst->tmpact);
-       }
-
-       /* duplicate NLA data */
-       if (src->nla_tracks.first) {
-               ListBase tracks = {NULL, NULL};
-
-               BKE_nla_tracks_copy(bmain, &tracks, &src->nla_tracks, 0);
-               BLI_movelisttolist(&dst->nla_tracks, &tracks);
-       }
-
-       /* duplicate drivers (F-Curves) */
-       if (src->drivers.first) {
-               ListBase drivers = {NULL, NULL};
-
-               copy_fcurves(&drivers, &src->drivers);
-
-               /* Fix up all driver targets using the old target id
-                * - This assumes that the src ID is being merged into the dst ID
-                */
-               if (fix_drivers) {
-                       FCurve *fcu;
-
-                       for (fcu = drivers.first; fcu; fcu = fcu->next) {
-                               ChannelDriver *driver = fcu->driver;
-                               DriverVar *dvar;
-
-                               for (dvar = driver->variables.first; dvar; dvar = dvar->next) {
-                                       DRIVER_TARGETS_USED_LOOPER_BEGIN(dvar)
-                                       {
-                                               if (dtar->id == src_id) {
-                                                       dtar->id = dst_id;
-                                               }
-                                       }
-                                       DRIVER_TARGETS_LOOPER_END;
-                               }
-                       }
-               }
-
-               BLI_movelisttolist(&dst->drivers, &drivers);
-       }
+    Main *bmain, ID *dst_id, ID *src_id, eAnimData_MergeCopy_Modes action_mode, bool fix_drivers)
+{
+  AnimData *src = BKE_animdata_from_id(src_id);
+  AnimData *dst = BKE_animdata_from_id(dst_id);
+
+  /* sanity checks */
+  if (ELEM(NULL, dst, src)) {
+    return;
+  }
+
+  // TODO: we must unset all "tweakmode" flags
+  if ((src->flag & ADT_NLA_EDIT_ON) || (dst->flag & ADT_NLA_EDIT_ON)) {
+    CLOG_ERROR(
+        &LOG,
+        "Merging AnimData blocks while editing NLA is dangerous as it may cause data corruption");
+    return;
+  }
+
+  /* handle actions... */
+  if (action_mode == ADT_MERGECOPY_SRC_COPY) {
+    /* make a copy of the actions */
+    dst->action = BKE_action_copy(bmain, src->action);
+    dst->tmpact = BKE_action_copy(bmain, src->tmpact);
+  }
+  else if (action_mode == ADT_MERGECOPY_SRC_REF) {
+    /* make a reference to it */
+    dst->action = src->action;
+    id_us_plus((ID *)dst->action);
+
+    dst->tmpact = src->tmpact;
+    id_us_plus((ID *)dst->tmpact);
+  }
+
+  /* duplicate NLA data */
+  if (src->nla_tracks.first) {
+    ListBase tracks = {NULL, NULL};
+
+    BKE_nla_tracks_copy(bmain, &tracks, &src->nla_tracks, 0);
+    BLI_movelisttolist(&dst->nla_tracks, &tracks);
+  }
+
+  /* duplicate drivers (F-Curves) */
+  if (src->drivers.first) {
+    ListBase drivers = {NULL, NULL};
+
+    copy_fcurves(&drivers, &src->drivers);
+
+    /* Fix up all driver targets using the old target id
+     * - This assumes that the src ID is being merged into the dst ID
+     */
+    if (fix_drivers) {
+      FCurve *fcu;
+
+      for (fcu = drivers.first; fcu; fcu = fcu->next) {
+        ChannelDriver *driver = fcu->driver;
+        DriverVar *dvar;
+
+        for (dvar = driver->variables.first; dvar; dvar = dvar->next) {
+          DRIVER_TARGETS_USED_LOOPER_BEGIN (dvar) {
+            if (dtar->id == src_id) {
+              dtar->id = dst_id;
+            }
+          }
+          DRIVER_TARGETS_LOOPER_END;
+        }
+      }
+    }
+
+    BLI_movelisttolist(&dst->drivers, &drivers);
+  }
 }
 
 /* Sub-ID Regrouping ------------------------------------------- */
@@ -429,8 +449,8 @@ void BKE_animdata_merge_copy(
  */
 static bool animpath_matches_basepath(const char path[], const char basepath[])
 {
-       /* we need start of path to be basepath */
-       return (path && basepath) && STRPREFIX(path, basepath);
+  /* we need start of path to be basepath */
+  return (path && basepath) && STRPREFIX(path, basepath);
 }
 
 /* Move F-Curves in src action to dst action, setting up all the necessary groups
@@ -441,155 +461,166 @@ static bool animpath_matches_basepath(const char path[], const char basepath[])
  */
 void action_move_fcurves_by_basepath(bAction *srcAct, bAction *dstAct, const char basepath[])
 {
-       FCurve *fcu, *fcn = NULL;
-
-       /* sanity checks */
-       if (ELEM(NULL, srcAct, dstAct, basepath)) {
-               if (G.debug & G_DEBUG) {
-                       CLOG_ERROR(&LOG, "srcAct: %p, dstAct: %p, basepath: %p has insufficient info to work with",
-                                  (void *)srcAct, (void *)dstAct, (void *)basepath);
-               }
-               return;
-       }
-
-       /* clear 'temp' flags on all groups in src, as we'll be needing them later
-        * to identify groups that we've managed to empty out here
-        */
-       action_groups_clear_tempflags(srcAct);
-
-       /* iterate over all src F-Curves, moving over the ones that need to be moved */
-       for (fcu = srcAct->curves.first; fcu; fcu = fcn) {
-               /* store next pointer in case we move stuff */
-               fcn = fcu->next;
-
-               /* should F-Curve be moved over?
-                * - we only need the start of the path to match basepath
-                */
-               if (animpath_matches_basepath(fcu->rna_path, basepath)) {
-                       bActionGroup *agrp = NULL;
-
-                       /* if grouped... */
-                       if (fcu->grp) {
-                               /* make sure there will be a matching group on the other side for the migrants */
-                               agrp = BKE_action_group_find_name(dstAct, fcu->grp->name);
-
-                               if (agrp == NULL) {
-                                       /* add a new one with a similar name (usually will be the same though) */
-                                       agrp = action_groups_add_new(dstAct, fcu->grp->name);
-                               }
-
-                               /* old groups should be tagged with 'temp' flags so they can be removed later
-                                * if we remove everything from them
-                                */
-                               fcu->grp->flag |= AGRP_TEMP;
-                       }
-
-                       /* perform the migration now */
-                       action_groups_remove_channel(srcAct, fcu);
-
-                       if (agrp)
-                               action_groups_add_channel(dstAct, agrp, fcu);
-                       else
-                               BLI_addtail(&dstAct->curves, fcu);
-               }
-       }
-
-       /* cleanup groups (if present) */
-       if (srcAct->groups.first) {
-               bActionGroup *agrp, *grp = NULL;
-
-               for (agrp = srcAct->groups.first; agrp; agrp = grp) {
-                       grp = agrp->next;
-
-                       /* only tagged groups need to be considered - clearing these tags or removing them */
-                       if (agrp->flag & AGRP_TEMP) {
-                               /* if group is empty and tagged, then we can remove as this operation
-                                * moved out all the channels that were formerly here
-                                */
-                               if (BLI_listbase_is_empty(&agrp->channels))
-                                       BLI_freelinkN(&srcAct->groups, agrp);
-                               else
-                                       agrp->flag &= ~AGRP_TEMP;
-                       }
-               }
-       }
+  FCurve *fcu, *fcn = NULL;
+
+  /* sanity checks */
+  if (ELEM(NULL, srcAct, dstAct, basepath)) {
+    if (G.debug & G_DEBUG) {
+      CLOG_ERROR(&LOG,
+                 "srcAct: %p, dstAct: %p, basepath: %p has insufficient info to work with",
+                 (void *)srcAct,
+                 (void *)dstAct,
+                 (void *)basepath);
+    }
+    return;
+  }
+
+  /* clear 'temp' flags on all groups in src, as we'll be needing them later
+   * to identify groups that we've managed to empty out here
+   */
+  action_groups_clear_tempflags(srcAct);
+
+  /* iterate over all src F-Curves, moving over the ones that need to be moved */
+  for (fcu = srcAct->curves.first; fcu; fcu = fcn) {
+    /* store next pointer in case we move stuff */
+    fcn = fcu->next;
+
+    /* should F-Curve be moved over?
+     * - we only need the start of the path to match basepath
+     */
+    if (animpath_matches_basepath(fcu->rna_path, basepath)) {
+      bActionGroup *agrp = NULL;
+
+      /* if grouped... */
+      if (fcu->grp) {
+        /* make sure there will be a matching group on the other side for the migrants */
+        agrp = BKE_action_group_find_name(dstAct, fcu->grp->name);
+
+        if (agrp == NULL) {
+          /* add a new one with a similar name (usually will be the same though) */
+          agrp = action_groups_add_new(dstAct, fcu->grp->name);
+        }
+
+        /* old groups should be tagged with 'temp' flags so they can be removed later
+         * if we remove everything from them
+         */
+        fcu->grp->flag |= AGRP_TEMP;
+      }
+
+      /* perform the migration now */
+      action_groups_remove_channel(srcAct, fcu);
+
+      if (agrp) {
+        action_groups_add_channel(dstAct, agrp, fcu);
+      }
+      else {
+        BLI_addtail(&dstAct->curves, fcu);
+      }
+    }
+  }
+
+  /* cleanup groups (if present) */
+  if (srcAct->groups.first) {
+    bActionGroup *agrp, *grp = NULL;
+
+    for (agrp = srcAct->groups.first; agrp; agrp = grp) {
+      grp = agrp->next;
+
+      /* only tagged groups need to be considered - clearing these tags or removing them */
+      if (agrp->flag & AGRP_TEMP) {
+        /* if group is empty and tagged, then we can remove as this operation
+         * moved out all the channels that were formerly here
+         */
+        if (BLI_listbase_is_empty(&agrp->channels)) {
+          BLI_freelinkN(&srcAct->groups, agrp);
+        }
+        else {
+          agrp->flag &= ~AGRP_TEMP;
+        }
+      }
+    }
+  }
 }
 
 /* Transfer the animation data from srcID to dstID where the srcID
  * animation data is based off "basepath", creating new AnimData and
  * associated data as necessary
  */
-void BKE_animdata_separate_by_basepath(
-        Main *bmain, ID *srcID, ID *dstID, ListBase *basepaths)
-{
-       AnimData *srcAdt = NULL, *dstAdt = NULL;
-       LinkData *ld;
-
-       /* sanity checks */
-       if (ELEM(NULL, srcID, dstID)) {
-               if (G.debug & G_DEBUG)
-                       CLOG_ERROR(&LOG, "no source or destination ID to separate AnimData with");
-               return;
-       }
-
-       /* get animdata from src, and create for destination (if needed) */
-       srcAdt = BKE_animdata_from_id(srcID);
-       dstAdt = BKE_animdata_add_id(dstID);
-
-       if (ELEM(NULL, srcAdt, dstAdt)) {
-               if (G.debug & G_DEBUG)
-                       CLOG_ERROR(&LOG, "no AnimData for this pair of ID's");
-               return;
-       }
-
-       /* active action */
-       if (srcAdt->action) {
-               /* set up an action if necessary, and name it in a similar way so that it can be easily found again */
-               if (dstAdt->action == NULL) {
-                       dstAdt->action = BKE_action_add(bmain, srcAdt->action->id.name + 2);
-               }
-               else if (dstAdt->action == srcAdt->action) {
-                       CLOG_WARN(&LOG, "Argh! Source and Destination share animation! "
-                                 "('%s' and '%s' both use '%s') Making new empty action",
-                                 srcID->name, dstID->name, srcAdt->action->id.name);
-
-                       /* TODO: review this... */
-                       id_us_min(&dstAdt->action->id);
-                       dstAdt->action = BKE_action_add(bmain, dstAdt->action->id.name + 2);
-               }
-
-               /* loop over base paths, trying to fix for each one... */
-               for (ld = basepaths->first; ld; ld = ld->next) {
-                       const char *basepath = (const char *)ld->data;
-                       action_move_fcurves_by_basepath(srcAdt->action, dstAdt->action, basepath);
-               }
-       }
-
-       /* drivers */
-       if (srcAdt->drivers.first) {
-               FCurve *fcu, *fcn = NULL;
-
-               /* check each driver against all the base paths to see if any should go */
-               for (fcu = srcAdt->drivers.first; fcu; fcu = fcn) {
-                       fcn = fcu->next;
-
-                       /* try each basepath in turn, but stop on the first one which works */
-                       for (ld = basepaths->first; ld; ld = ld->next) {
-                               const char *basepath = (const char *)ld->data;
-
-                               if (animpath_matches_basepath(fcu->rna_path, basepath)) {
-                                       /* just need to change lists */
-                                       BLI_remlink(&srcAdt->drivers, fcu);
-                                       BLI_addtail(&dstAdt->drivers, fcu);
-
-                                       /* TODO: add depsgraph flushing calls? */
-
-                                       /* can stop now, as moved already */
-                                       break;
-                               }
-                       }
-               }
-       }
+void BKE_animdata_separate_by_basepath(Main *bmain, ID *srcID, ID *dstID, ListBase *basepaths)
+{
+  AnimData *srcAdt = NULL, *dstAdt = NULL;
+  LinkData *ld;
+
+  /* sanity checks */
+  if (ELEM(NULL, srcID, dstID)) {
+    if (G.debug & G_DEBUG) {
+      CLOG_ERROR(&LOG, "no source or destination ID to separate AnimData with");
+    }
+    return;
+  }
+
+  /* get animdata from src, and create for destination (if needed) */
+  srcAdt = BKE_animdata_from_id(srcID);
+  dstAdt = BKE_animdata_add_id(dstID);
+
+  if (ELEM(NULL, srcAdt, dstAdt)) {
+    if (G.debug & G_DEBUG) {
+      CLOG_ERROR(&LOG, "no AnimData for this pair of ID's");
+    }
+    return;
+  }
+
+  /* active action */
+  if (srcAdt->action) {
+    /* set up an action if necessary, and name it in a similar way so that it can be easily found again */
+    if (dstAdt->action == NULL) {
+      dstAdt->action = BKE_action_add(bmain, srcAdt->action->id.name + 2);
+    }
+    else if (dstAdt->action == srcAdt->action) {
+      CLOG_WARN(&LOG,
+                "Argh! Source and Destination share animation! "
+                "('%s' and '%s' both use '%s') Making new empty action",
+                srcID->name,
+                dstID->name,
+                srcAdt->action->id.name);
+
+      /* TODO: review this... */
+      id_us_min(&dstAdt->action->id);
+      dstAdt->action = BKE_action_add(bmain, dstAdt->action->id.name + 2);
+    }
+
+    /* loop over base paths, trying to fix for each one... */
+    for (ld = basepaths->first; ld; ld = ld->next) {
+      const char *basepath = (const char *)ld->data;
+      action_move_fcurves_by_basepath(srcAdt->action, dstAdt->action, basepath);
+    }
+  }
+
+  /* drivers */
+  if (srcAdt->drivers.first) {
+    FCurve *fcu, *fcn = NULL;
+
+    /* check each driver against all the base paths to see if any should go */
+    for (fcu = srcAdt->drivers.first; fcu; fcu = fcn) {
+      fcn = fcu->next;
+
+      /* try each basepath in turn, but stop on the first one which works */
+      for (ld = basepaths->first; ld; ld = ld->next) {
+        const char *basepath = (const char *)ld->data;
+
+        if (animpath_matches_basepath(fcu->rna_path, basepath)) {
+          /* just need to change lists */
+          BLI_remlink(&srcAdt->drivers, fcu);
+          BLI_addtail(&dstAdt->drivers, fcu);
+
+          /* TODO: add depsgraph flushing calls? */
+
+          /* can stop now, as moved already */
+          break;
+        }
+      }
+    }
+  }
 }
 
 /**
@@ -602,36 +633,39 @@ void BKE_animdata_separate_by_basepath(
  * \param prop: RNA definition of property to add for
  * \return MEM_alloc'd string representing the path to the property from the given #PointerRNA
  */
-char *BKE_animdata_driver_path_hack(bContext *C, PointerRNA *ptr, PropertyRNA *prop, char *base_path)
+char *BKE_animdata_driver_path_hack(bContext *C,
+                                    PointerRNA *ptr,
+                                    PropertyRNA *prop,
+                                    char *base_path)
 {
-       ID *id = (ID *)ptr->id.data;
-       ScrArea *sa = CTX_wm_area(C);
+  ID *id = (ID *)ptr->id.data;
+  ScrArea *sa = CTX_wm_area(C);
 
-       /* get standard path which may be extended */
-       char *basepath = base_path ? base_path : RNA_path_from_ID_to_property(ptr, prop);
-       char *path = basepath; /* in case no remapping is needed */
+  /* get standard path which may be extended */
+  char *basepath = base_path ? base_path : RNA_path_from_ID_to_property(ptr, prop);
+  char *path = basepath; /* in case no remapping is needed */
 
-       /* Remapping will only be performed in the Properties Editor, as only this
-        * restricts the subspace of options to the 'active' data (a manageable state)
-        */
-       /* TODO: watch out for pinned context? */
-       if ((sa) && (sa->spacetype == SPACE_PROPERTIES)) {
-               Object *ob = CTX_data_active_object(C);
+  /* Remapping will only be performed in the Properties Editor, as only this
+   * restricts the subspace of options to the 'active' data (a manageable state)
+   */
+  /* TODO: watch out for pinned context? */
+  if ((sa) && (sa->spacetype == SPACE_PROPERTIES)) {
+    Object *ob = CTX_data_active_object(C);
 
-               if (ob && id) {
-                       /* TODO: after material textures were removed, this function serves
-                        * no purpose anymore, but could be used again so was not removed. */
+    if (ob && id) {
+      /* TODO: after material textures were removed, this function serves
+       * no purpose anymore, but could be used again so was not removed. */
 
-                       /* fix RNA pointer, as we've now changed the ID root by changing the paths */
-                       if (basepath != path) {
-                               /* rebase provided pointer so that it starts from object... */
-                               RNA_pointer_create(&ob->id, ptr->type, ptr->data, ptr);
-                       }
-               }
-       }
+      /* fix RNA pointer, as we've now changed the ID root by changing the paths */
+      if (basepath != path) {
+        /* rebase provided pointer so that it starts from object... */
+        RNA_pointer_create(&ob->id, ptr->type, ptr->data, ptr);
+      }
+    }
+  }
 
-       /* the path should now have been corrected for use */
-       return path;
+  /* the path should now have been corrected for use */
+  return path;
 }
 
 /* Path Validation -------------------------------------------- */
@@ -639,164 +673,190 @@ char *BKE_animdata_driver_path_hack(bContext *C, PointerRNA *ptr, PropertyRNA *p
 /* Check if a given RNA Path is valid, by tracing it from the given ID, and seeing if we can resolve it */
 static bool check_rna_path_is_valid(ID *owner_id, const char *path)
 {
-       PointerRNA id_ptr, ptr;
-       PropertyRNA *prop = NULL;
+  PointerRNA id_ptr, ptr;
+  PropertyRNA *prop = NULL;
 
-       /* make initial RNA pointer to start resolving from */
-       RNA_id_pointer_create(owner_id, &id_ptr);
+  /* make initial RNA pointer to start resolving from */
+  RNA_id_pointer_create(owner_id, &id_ptr);
 
-       /* try to resolve */
-       return RNA_path_resolve_property(&id_ptr, path, &ptr, &prop);
+  /* try to resolve */
+  return RNA_path_resolve_property(&id_ptr, path, &ptr, &prop);
 }
 
 /* Check if some given RNA Path needs fixing - free the given path and set a new one as appropriate
  * NOTE: we assume that oldName and newName have [" "] padding around them
  */
-static char *rna_path_rename_fix(ID *owner_id, const char *prefix, const char *oldName, const char *newName, char *oldpath, bool verify_paths)
-{
-       char *prefixPtr = strstr(oldpath, prefix);
-       char *oldNamePtr = strstr(oldpath, oldName);
-       int prefixLen = strlen(prefix);
-       int oldNameLen = strlen(oldName);
-
-       /* only start fixing the path if the prefix and oldName feature in the path,
-        * and prefix occurs immediately before oldName
-        */
-       if ( (prefixPtr && oldNamePtr) && (prefixPtr + prefixLen == oldNamePtr) ) {
-               /* if we haven't aren't able to resolve the path now, try again after fixing it */
-               if (!verify_paths || check_rna_path_is_valid(owner_id, oldpath) == 0) {
-                       DynStr *ds = BLI_dynstr_new();
-                       const char *postfixPtr = oldNamePtr + oldNameLen;
-                       char *newPath = NULL;
-
-                       /* add the part of the string that goes up to the start of the prefix */
-                       if (prefixPtr > oldpath) {
-                               BLI_dynstr_nappend(ds, oldpath, prefixPtr - oldpath);
-                       }
-
-                       /* add the prefix */
-                       BLI_dynstr_append(ds, prefix);
-
-                       /* add the new name (complete with brackets) */
-                       BLI_dynstr_append(ds, newName);
-
-                       /* add the postfix */
-                       BLI_dynstr_append(ds, postfixPtr);
-
-                       /* create new path, and cleanup old data */
-                       newPath = BLI_dynstr_get_cstring(ds);
-                       BLI_dynstr_free(ds);
-
-                       /* check if the new path will solve our problems */
-                       /* TODO: will need to check whether this step really helps in practice */
-                       if (!verify_paths || check_rna_path_is_valid(owner_id, newPath)) {
-                               /* free the old path, and return the new one, since we've solved the issues */
-                               MEM_freeN(oldpath);
-                               return newPath;
-                       }
-                       else {
-                               /* still couldn't resolve the path... so, might as well just leave it alone */
-                               MEM_freeN(newPath);
-                       }
-               }
-       }
-
-       /* the old path doesn't need to be changed */
-       return oldpath;
+static char *rna_path_rename_fix(ID *owner_id,
+                                 const char *prefix,
+                                 const char *oldName,
+                                 const char *newName,
+                                 char *oldpath,
+                                 bool verify_paths)
+{
+  char *prefixPtr = strstr(oldpath, prefix);
+  char *oldNamePtr = strstr(oldpath, oldName);
+  int prefixLen = strlen(prefix);
+  int oldNameLen = strlen(oldName);
+
+  /* only start fixing the path if the prefix and oldName feature in the path,
+   * and prefix occurs immediately before oldName
+   */
+  if ((prefixPtr && oldNamePtr) && (prefixPtr + prefixLen == oldNamePtr)) {
+    /* if we haven't aren't able to resolve the path now, try again after fixing it */
+    if (!verify_paths || check_rna_path_is_valid(owner_id, oldpath) == 0) {
+      DynStr *ds = BLI_dynstr_new();
+      const char *postfixPtr = oldNamePtr + oldNameLen;
+      char *newPath = NULL;
+
+      /* add the part of the string that goes up to the start of the prefix */
+      if (prefixPtr > oldpath) {
+        BLI_dynstr_nappend(ds, oldpath, prefixPtr - oldpath);
+      }
+
+      /* add the prefix */
+      BLI_dynstr_append(ds, prefix);
+
+      /* add the new name (complete with brackets) */
+      BLI_dynstr_append(ds, newName);
+
+      /* add the postfix */
+      BLI_dynstr_append(ds, postfixPtr);
+
+      /* create new path, and cleanup old data */
+      newPath = BLI_dynstr_get_cstring(ds);
+      BLI_dynstr_free(ds);
+
+      /* check if the new path will solve our problems */
+      /* TODO: will need to check whether this step really helps in practice */
+      if (!verify_paths || check_rna_path_is_valid(owner_id, newPath)) {
+        /* free the old path, and return the new one, since we've solved the issues */
+        MEM_freeN(oldpath);
+        return newPath;
+      }
+      else {
+        /* still couldn't resolve the path... so, might as well just leave it alone */
+        MEM_freeN(newPath);
+      }
+    }
+  }
+
+  /* the old path doesn't need to be changed */
+  return oldpath;
 }
 
 /* Check RNA-Paths for a list of F-Curves */
-static bool fcurves_path_rename_fix(ID *owner_id, const char *prefix, const char *oldName, const char *newName,
-                                    const char *oldKey, const char *newKey, ListBase *curves, bool verify_paths)
-{
-       FCurve *fcu;
-       bool is_changed = false;
-       /* We need to check every curve. */
-       for (fcu = curves->first; fcu; fcu = fcu->next) {
-               if (fcu->rna_path == NULL) {
-                       continue;
-               }
-               const char *old_path = fcu->rna_path;
-               /* Firstly, handle the F-Curve's own path. */
-               fcu->rna_path = rna_path_rename_fix(owner_id, prefix, oldKey, newKey, fcu->rna_path, verify_paths);
-               /* if path changed and the F-Curve is grouped, check if its group also needs renaming
-                * (i.e. F-Curve is first of a bone's F-Curves; hence renaming this should also trigger rename) */
-               if (fcu->rna_path != old_path) {
-                       bActionGroup *agrp = fcu->grp;
-                       is_changed = true;
-                       if ((agrp != NULL) && STREQ(oldName, agrp->name)) {
-                               BLI_strncpy(agrp->name, newName, sizeof(agrp->name));
-                       }
-               }
-       }
-       return is_changed;
+static bool fcurves_path_rename_fix(ID *owner_id,
+                                    const char *prefix,
+                                    const char *oldName,
+                                    const char *newName,
+                                    const char *oldKey,
+                                    const char *newKey,
+                                    ListBase *curves,
+                                    bool verify_paths)
+{
+  FCurve *fcu;
+  bool is_changed = false;
+  /* We need to check every curve. */
+  for (fcu = curves->first; fcu; fcu = fcu->next) {
+    if (fcu->rna_path == NULL) {
+      continue;
+    }
+    const char *old_path = fcu->rna_path;
+    /* Firstly, handle the F-Curve's own path. */
+    fcu->rna_path = rna_path_rename_fix(
+        owner_id, prefix, oldKey, newKey, fcu->rna_path, verify_paths);
+    /* if path changed and the F-Curve is grouped, check if its group also needs renaming
+     * (i.e. F-Curve is first of a bone's F-Curves; hence renaming this should also trigger rename) */
+    if (fcu->rna_path != old_path) {
+      bActionGroup *agrp = fcu->grp;
+      is_changed = true;
+      if ((agrp != NULL) && STREQ(oldName, agrp->name)) {
+        BLI_strncpy(agrp->name, newName, sizeof(agrp->name));
+      }
+    }
+  }
+  return is_changed;
 }
 
 /* Check RNA-Paths for a list of Drivers */
-static bool drivers_path_rename_fix(ID *owner_id, ID *ref_id, const char *prefix, const char *oldName, const char *newName,
-                                    const char *oldKey, const char *newKey, ListBase *curves, bool verify_paths)
-{
-       bool is_changed = false;
-       FCurve *fcu;
-       /* We need to check every curve - drivers are F-Curves too. */
-       for (fcu = curves->first; fcu; fcu = fcu->next) {
-               /* firstly, handle the F-Curve's own path */
-               if (fcu->rna_path != NULL) {
-                       const char *old_rna_path = fcu->rna_path;
-                       fcu->rna_path = rna_path_rename_fix(owner_id, prefix, oldKey, newKey, fcu->rna_path, verify_paths);
-                       is_changed |= (fcu->rna_path != old_rna_path);
-               }
-               if (fcu->driver == NULL) {
-                       continue;
-               }
-               ChannelDriver *driver = fcu->driver;
-               DriverVar *dvar;
-               /* driver variables */
-               for (dvar = driver->variables.first; dvar; dvar = dvar->next) {
-                       /* only change the used targets, since the others will need fixing manually anyway */
-                       DRIVER_TARGETS_USED_LOOPER_BEGIN(dvar)
-                       {
-                               /* rename RNA path */
-                               if (dtar->rna_path && dtar->id) {
-                                       const char *old_rna_path = dtar->rna_path;
-                                       dtar->rna_path = rna_path_rename_fix(dtar->id, prefix, oldKey, newKey, dtar->rna_path, verify_paths);
-                                       is_changed |= (dtar->rna_path != old_rna_path);
-                               }
-                               /* also fix the bone-name (if applicable) */
-                               if (strstr(prefix, "bones")) {
-                                       if ( ((dtar->id) && (GS(dtar->id->name) == ID_OB) && (!ref_id || ((Object *)(dtar->id))->data == ref_id)) &&
-                                            (dtar->pchan_name[0]) && STREQ(oldName, dtar->pchan_name) )
-                                       {
-                                               is_changed = true;
-                                               BLI_strncpy(dtar->pchan_name, newName, sizeof(dtar->pchan_name));
-                                       }
-                               }
-                       }
-                       DRIVER_TARGETS_LOOPER_END;
-               }
-       }
-       return is_changed;
+static bool drivers_path_rename_fix(ID *owner_id,
+                                    ID *ref_id,
+                                    const char *prefix,
+                                    const char *oldName,
+                                    const char *newName,
+                                    const char *oldKey,
+                                    const char *newKey,
+                                    ListBase *curves,
+                                    bool verify_paths)
+{
+  bool is_changed = false;
+  FCurve *fcu;
+  /* We need to check every curve - drivers are F-Curves too. */
+  for (fcu = curves->first; fcu; fcu = fcu->next) {
+    /* firstly, handle the F-Curve's own path */
+    if (fcu->rna_path != NULL) {
+      const char *old_rna_path = fcu->rna_path;
+      fcu->rna_path = rna_path_rename_fix(
+          owner_id, prefix, oldKey, newKey, fcu->rna_path, verify_paths);
+      is_changed |= (fcu->rna_path != old_rna_path);
+    }
+    if (fcu->driver == NULL) {
+      continue;
+    }
+    ChannelDriver *driver = fcu->driver;
+    DriverVar *dvar;
+    /* driver variables */
+    for (dvar = driver->variables.first; dvar; dvar = dvar->next) {
+      /* only change the used targets, since the others will need fixing manually anyway */
+      DRIVER_TARGETS_USED_LOOPER_BEGIN (dvar) {
+        /* rename RNA path */
+        if (dtar->rna_path && dtar->id) {
+          const char *old_rna_path = dtar->rna_path;
+          dtar->rna_path = rna_path_rename_fix(
+              dtar->id, prefix, oldKey, newKey, dtar->rna_path, verify_paths);
+          is_changed |= (dtar->rna_path != old_rna_path);
+        }
+        /* also fix the bone-name (if applicable) */
+        if (strstr(prefix, "bones")) {
+          if (((dtar->id) && (GS(dtar->id->name) == ID_OB) &&
+               (!ref_id || ((Object *)(dtar->id))->data == ref_id)) &&
+              (dtar->pchan_name[0]) && STREQ(oldName, dtar->pchan_name)) {
+            is_changed = true;
+            BLI_strncpy(dtar->pchan_name, newName, sizeof(dtar->pchan_name));
+          }
+        }
+      }
+      DRIVER_TARGETS_LOOPER_END;
+    }
+  }
+  return is_changed;
 }
 
 /* Fix all RNA-Paths for Actions linked to NLA Strips */
-static bool nlastrips_path_rename_fix(ID *owner_id, const char *prefix, const char *oldName, const char *newName,
-                                      const char *oldKey, const char *newKey, ListBase *strips, bool verify_paths)
-{
-       NlaStrip *strip;
-       bool is_changed = false;
-       /* Recursively check strips, fixing only actions. */
-       for (strip = strips->first; strip; strip = strip->next) {
-               /* fix strip's action */
-               if (strip->act != NULL) {
-                       is_changed |= fcurves_path_rename_fix(
-                               owner_id, prefix, oldName, newName, oldKey, newKey, &strip->act->curves, verify_paths);
-               }
-               /* Ignore own F-Curves, since those are local.  */
-               /* Check sub-strips (if metas) */
-               is_changed |= nlastrips_path_rename_fix(
-                       owner_id, prefix, oldName, newName, oldKey, newKey, &strip->strips, verify_paths);
-       }
-       return is_changed;
+static bool nlastrips_path_rename_fix(ID *owner_id,
+                                      const char *prefix,
+                                      const char *oldName,
+                                      const char *newName,
+                                      const char *oldKey,
+                                      const char *newKey,
+                                      ListBase *strips,
+                                      bool verify_paths)
+{
+  NlaStrip *strip;
+  bool is_changed = false;
+  /* Recursively check strips, fixing only actions. */
+  for (strip = strips->first; strip; strip = strip->next) {
+    /* fix strip's action */
+    if (strip->act != NULL) {
+      is_changed |= fcurves_path_rename_fix(
+          owner_id, prefix, oldName, newName, oldKey, newKey, &strip->act->curves, verify_paths);
+    }
+    /* Ignore own F-Curves, since those are local.  */
+    /* Check sub-strips (if metas) */
+    is_changed |= nlastrips_path_rename_fix(
+        owner_id, prefix, oldName, newName, oldKey, newKey, &strip->strips, verify_paths);
+  }
+  return is_changed;
 }
 
 /* Rename Sub-ID Entities in RNA Paths ----------------------- */
@@ -809,47 +869,59 @@ static bool nlastrips_path_rename_fix(ID *owner_id, const char *prefix, const ch
  * NOTE: it is assumed that the structure we're replacing is <prefix><["><name><"]>
  *       i.e. pose.bones["Bone"]
  */
-char *BKE_animsys_fix_rna_path_rename(ID *owner_id, char *old_path, const char *prefix, const char *oldName,
-                                      const char *newName, int oldSubscript, int newSubscript, bool verify_paths)
-{
-       char *oldN, *newN;
-       char *result;
-
-       /* if no action, no need to proceed */
-       if (ELEM(NULL, owner_id, old_path)) {
-               if (G.debug & G_DEBUG) CLOG_WARN(&LOG, "early abort");
-               return old_path;
-       }
-
-       /* Name sanitation logic - copied from BKE_animdata_fix_paths_rename() */
-       if ((oldName != NULL) && (newName != NULL)) {
-               /* pad the names with [" "] so that only exact matches are made */
-               const size_t name_old_len = strlen(oldName);
-               const size_t name_new_len = strlen(newName);
-               char *name_old_esc = BLI_array_alloca(name_old_esc, (name_old_len * 2) + 1);
-               char *name_new_esc = BLI_array_alloca(name_new_esc, (name_new_len * 2) + 1);
-
-               BLI_strescape(name_old_esc, oldName, (name_old_len * 2) + 1);
-               BLI_strescape(name_new_esc, newName, (name_new_len * 2) + 1);
-               oldN = BLI_sprintfN("[\"%s\"]", name_old_esc);
-               newN = BLI_sprintfN("[\"%s\"]", name_new_esc);
-       }
-       else {
-               oldN = BLI_sprintfN("[%d]", oldSubscript);
-               newN = BLI_sprintfN("[%d]", newSubscript);
-       }
-
-       /* fix given path */
-       if (G.debug & G_DEBUG) printf("%s | %s  | oldpath = %p ", oldN, newN, old_path);
-       result = rna_path_rename_fix(owner_id, prefix, oldN, newN, old_path, verify_paths);
-       if (G.debug & G_DEBUG) printf("path rename result = %p\n", result);
-
-       /* free the temp names */
-       MEM_freeN(oldN);
-       MEM_freeN(newN);
-
-       /* return the resulting path - may be the same path again if nothing changed */
-       return result;
+char *BKE_animsys_fix_rna_path_rename(ID *owner_id,
+                                      char *old_path,
+                                      const char *prefix,
+                                      const char *oldName,
+                                      const char *newName,
+                                      int oldSubscript,
+                                      int newSubscript,
+                                      bool verify_paths)
+{
+  char *oldN, *newN;
+  char *result;
+
+  /* if no action, no need to proceed */
+  if (ELEM(NULL, owner_id, old_path)) {
+    if (G.debug & G_DEBUG) {
+      CLOG_WARN(&LOG, "early abort");
+    }
+    return old_path;
+  }
+
+  /* Name sanitation logic - copied from BKE_animdata_fix_paths_rename() */
+  if ((oldName != NULL) && (newName != NULL)) {
+    /* pad the names with [" "] so that only exact matches are made */
+    const size_t name_old_len = strlen(oldName);
+    const size_t name_new_len = strlen(newName);
+    char *name_old_esc = BLI_array_alloca(name_old_esc, (name_old_len * 2) + 1);
+    char *name_new_esc = BLI_array_alloca(name_new_esc, (name_new_len * 2) + 1);
+
+    BLI_strescape(name_old_esc, oldName, (name_old_len * 2) + 1);
+    BLI_strescape(name_new_esc, newName, (name_new_len * 2) + 1);
+    oldN = BLI_sprintfN("[\"%s\"]", name_old_esc);
+    newN = BLI_sprintfN("[\"%s\"]", name_new_esc);
+  }
+  else {
+    oldN = BLI_sprintfN("[%d]", oldSubscript);
+    newN = BLI_sprintfN("[%d]", newSubscript);
+  }
+
+  /* fix given path */
+  if (G.debug & G_DEBUG) {
+    printf("%s | %s  | oldpath = %p ", oldN, newN, old_path);
+  }
+  result = rna_path_rename_fix(owner_id, prefix, oldN, newN, old_path, verify_paths);
+  if (G.debug & G_DEBUG) {
+    printf("path rename result = %p\n", result);
+  }
+
+  /* free the temp names */
+  MEM_freeN(oldN);
+  MEM_freeN(newN);
+
+  /* return the resulting path - may be the same path again if nothing changed */
+  return result;
 }
 
 /* Fix all RNA_Paths in the given Action, relative to the given ID block
@@ -860,102 +932,115 @@ char *BKE_animsys_fix_rna_path_rename(ID *owner_id, char *old_path, const char *
  * NOTE: it is assumed that the structure we're replacing is <prefix><["><name><"]>
  *       i.e. pose.bones["Bone"]
  */
-void BKE_action_fix_paths_rename(ID *owner_id, bAction *act, const char *prefix, const char *oldName,
-                                 const char *newName, int oldSubscript, int newSubscript, bool verify_paths)
-{
-       char *oldN, *newN;
-
-       /* if no action, no need to proceed */
-       if (ELEM(NULL, owner_id, act))
-               return;
-
-       /* Name sanitation logic - copied from BKE_animdata_fix_paths_rename() */
-       if ((oldName != NULL) && (newName != NULL)) {
-               /* pad the names with [" "] so that only exact matches are made */
-               const size_t name_old_len = strlen(oldName);
-               const size_t name_new_len = strlen(newName);
-               char *name_old_esc = BLI_array_alloca(name_old_esc, (name_old_len * 2) + 1);
-               char *name_new_esc = BLI_array_alloca(name_new_esc, (name_new_len * 2) + 1);
-
-               BLI_strescape(name_old_esc, oldName, (name_old_len * 2) + 1);
-               BLI_strescape(name_new_esc, newName, (name_new_len * 2) + 1);
-               oldN = BLI_sprintfN("[\"%s\"]", name_old_esc);
-               newN = BLI_sprintfN("[\"%s\"]", name_new_esc);
-       }
-       else {
-               oldN = BLI_sprintfN("[%d]", oldSubscript);
-               newN = BLI_sprintfN("[%d]", newSubscript);
-       }
-
-       /* fix paths in action */
-       fcurves_path_rename_fix(owner_id, prefix, oldName, newName, oldN, newN, &act->curves, verify_paths);
-
-       /* free the temp names */
-       MEM_freeN(oldN);
-       MEM_freeN(newN);
+void BKE_action_fix_paths_rename(ID *owner_id,
+                                 bAction *act,
+                                 const char *prefix,
+                                 const char *oldName,
+                                 const char *newName,
+                                 int oldSubscript,
+                                 int newSubscript,
+                                 bool verify_paths)
+{
+  char *oldN, *newN;
+
+  /* if no action, no need to proceed */
+  if (ELEM(NULL, owner_id, act)) {
+    return;
+  }
+
+  /* Name sanitation logic - copied from BKE_animdata_fix_paths_rename() */
+  if ((oldName != NULL) && (newName != NULL)) {
+    /* pad the names with [" "] so that only exact matches are made */
+    const size_t name_old_len = strlen(oldName);
+    const size_t name_new_len = strlen(newName);
+    char *name_old_esc = BLI_array_alloca(name_old_esc, (name_old_len * 2) + 1);
+    char *name_new_esc = BLI_array_alloca(name_new_esc, (name_new_len * 2) + 1);
+
+    BLI_strescape(name_old_esc, oldName, (name_old_len * 2) + 1);
+    BLI_strescape(name_new_esc, newName, (name_new_len * 2) + 1);
+    oldN = BLI_sprintfN("[\"%s\"]", name_old_esc);
+    newN = BLI_sprintfN("[\"%s\"]", name_new_esc);
+  }
+  else {
+    oldN = BLI_sprintfN("[%d]", oldSubscript);
+    newN = BLI_sprintfN("[%d]", newSubscript);
+  }
+
+  /* fix paths in action */
+  fcurves_path_rename_fix(
+      owner_id, prefix, oldName, newName, oldN, newN, &act->curves, verify_paths);
+
+  /* free the temp names */
+  MEM_freeN(oldN);
+  MEM_freeN(newN);
 }
 
 /* Fix all RNA-Paths in the AnimData block used by the given ID block
  * NOTE: it is assumed that the structure we're replacing is <prefix><["><name><"]>
  *       i.e. pose.bones["Bone"]
  */
-void BKE_animdata_fix_paths_rename(ID *owner_id, AnimData *adt, ID *ref_id, const char *prefix, const char *oldName,
-                                   const char *newName, int oldSubscript, int newSubscript, bool verify_paths)
-{
-       NlaTrack *nlt;
-       char *oldN, *newN;
-       /* If no AnimData, no need to proceed. */
-       if (ELEM(NULL, owner_id, adt)) {
-               return;
-       }
-       bool is_self_changed = false;
-       /* Name sanitation logic - shared with BKE_action_fix_paths_rename(). */
-       if ((oldName != NULL) && (newName != NULL)) {
-               /* Pad the names with [" "] so that only exact matches are made. */
-               const size_t name_old_len = strlen(oldName);
-               const size_t name_new_len = strlen(newName);
-               char *name_old_esc = BLI_array_alloca(name_old_esc, (name_old_len * 2) + 1);
-               char *name_new_esc = BLI_array_alloca(name_new_esc, (name_new_len * 2) + 1);
-
-               BLI_strescape(name_old_esc, oldName, (name_old_len * 2) + 1);
-               BLI_strescape(name_new_esc, newName, (name_new_len * 2) + 1);
-               oldN = BLI_sprintfN("[\"%s\"]", name_old_esc);
-               newN = BLI_sprintfN("[\"%s\"]", name_new_esc);
-       }
-       else {
-               oldN = BLI_sprintfN("[%d]", oldSubscript);
-               newN = BLI_sprintfN("[%d]", newSubscript);
-       }
-       /* Active action and temp action. */
-       if (adt->action != NULL) {
-               if (fcurves_path_rename_fix(owner_id, prefix, oldName, newName,
-                                           oldN, newN, &adt->action->curves, verify_paths))
-               {
-                       DEG_id_tag_update(&adt->action->id, ID_RECALC_COPY_ON_WRITE);
-               }
-       }
-       if (adt->tmpact) {
-               if (fcurves_path_rename_fix(owner_id, prefix, oldName, newName,
-                                           oldN, newN, &adt->tmpact->curves, verify_paths))
-               {
-                       DEG_id_tag_update(&adt->tmpact->id, ID_RECALC_COPY_ON_WRITE);
-               }
-       }
-       /* Drivers - Drivers are really F-Curves */
-       is_self_changed |= drivers_path_rename_fix(
-                owner_id, ref_id, prefix, oldName, newName, oldN, newN, &adt->drivers, verify_paths);
-       /* NLA Data - Animation Data for Strips */
-       for (nlt = adt->nla_tracks.first; nlt; nlt = nlt->next) {
-               is_self_changed |= nlastrips_path_rename_fix(
-                       owner_id, prefix, oldName, newName, oldN, newN, &nlt->strips, verify_paths);
-       }
-       /* Tag owner ID if it */
-       if (is_self_changed) {
-               DEG_id_tag_update(owner_id, ID_RECALC_COPY_ON_WRITE);
-       }
-       /* free the temp names */
-       MEM_freeN(oldN);
-       MEM_freeN(newN);
+void BKE_animdata_fix_paths_rename(ID *owner_id,
+                                   AnimData *adt,
+                                   ID *ref_id,
+                                   const char *prefix,
+                                   const char *oldName,
+                                   const char *newName,
+                                   int oldSubscript,
+                                   int newSubscript,
+                                   bool verify_paths)
+{
+  NlaTrack *nlt;
+  char *oldN, *newN;
+  /* If no AnimData, no need to proceed. */
+  if (ELEM(NULL, owner_id, adt)) {
+    return;
+  }
+  bool is_self_changed = false;
+  /* Name sanitation logic - shared with BKE_action_fix_paths_rename(). */
+  if ((oldName != NULL) && (newName != NULL)) {
+    /* Pad the names with [" "] so that only exact matches are made. */
+    const size_t name_old_len = strlen(oldName);
+    const size_t name_new_len = strlen(newName);
+    char *name_old_esc = BLI_array_alloca(name_old_esc, (name_old_len * 2) + 1);
+    char *name_new_esc = BLI_array_alloca(name_new_esc, (name_new_len * 2) + 1);
+
+    BLI_strescape(name_old_esc, oldName, (name_old_len * 2) + 1);
+    BLI_strescape(name_new_esc, newName, (name_new_len * 2) + 1);
+    oldN = BLI_sprintfN("[\"%s\"]", name_old_esc);
+    newN = BLI_sprintfN("[\"%s\"]", name_new_esc);
+  }
+  else {
+    oldN = BLI_sprintfN("[%d]", oldSubscript);
+    newN = BLI_sprintfN("[%d]", newSubscript);
+  }
+  /* Active action and temp action. */
+  if (adt->action != NULL) {
+    if (fcurves_path_rename_fix(
+            owner_id, prefix, oldName, newName, oldN, newN, &adt->action->curves, verify_paths)) {
+      DEG_id_tag_update(&adt->action->id, ID_RECALC_COPY_ON_WRITE);
+    }
+  }
+  if (adt->tmpact) {
+    if (fcurves_path_rename_fix(
+            owner_id, prefix, oldName, newName, oldN, newN, &adt->tmpact->curves, verify_paths)) {
+      DEG_id_tag_update(&adt->tmpact->id, ID_RECALC_COPY_ON_WRITE);
+    }
+  }
+  /* Drivers - Drivers are really F-Curves */
+  is_self_changed |= drivers_path_rename_fix(
+      owner_id, ref_id, prefix, oldName, newName, oldN, newN, &adt->drivers, verify_paths);
+  /* NLA Data - Animation Data for Strips */
+  for (nlt = adt->nla_tracks.first; nlt; nlt = nlt->next) {
+    is_self_changed |= nlastrips_path_rename_fix(
+        owner_id, prefix, oldName, newName, oldN, newN, &nlt->strips, verify_paths);
+  }
+  /* Tag owner ID if it */
+  if (is_self_changed) {
+    DEG_id_tag_update(owner_id, ID_RECALC_COPY_ON_WRITE);
+  }
+  /* free the temp names */
+  MEM_freeN(oldN);
+  MEM_freeN(newN);
 }
 
 /* Remove FCurves with Prefix  -------------------------------------- */
@@ -963,233 +1048,251 @@ void BKE_animdata_fix_paths_rename(ID *owner_id, AnimData *adt, ID *ref_id, cons
 /* Check RNA-Paths for a list of F-Curves */
 static bool fcurves_path_remove_fix(const char *prefix, ListBase *curves)
 {
-       FCurve *fcu, *fcn;
-       bool any_removed = false;
-       if (!prefix) return any_removed;
+  FCurve *fcu, *fcn;
+  bool any_removed = false;
+  if (!prefix) {
+    return any_removed;
+  }
 
-       /* we need to check every curve... */
-       for (fcu = curves->first; fcu; fcu = fcn) {
-               fcn = fcu->next;
+  /* we need to check every curve... */
+  for (fcu = curves->first; fcu; fcu = fcn) {
+    fcn = fcu->next;
 
-               if (fcu->rna_path) {
-                       if (STRPREFIX(fcu->rna_path, prefix)) {
-                               BLI_remlink(curves, fcu);
-                               free_fcurve(fcu);
-                               any_removed = true;
-                       }
-               }
-       }
-       return any_removed;
+    if (fcu->rna_path) {
+      if (STRPREFIX(fcu->rna_path, prefix)) {
+        BLI_remlink(curves, fcu);
+        free_fcurve(fcu);
+        any_removed = true;
+      }
+    }
+  }
+  return any_removed;
 }
 
 /* Check RNA-Paths for a list of F-Curves */
 static bool nlastrips_path_remove_fix(const char *prefix, ListBase *strips)
 {
-       NlaStrip *strip;
-       bool any_removed = false;
+  NlaStrip *strip;
+  bool any_removed = false;
 
-       /* recursively check strips, fixing only actions... */
-       for (strip = strips->first; strip; strip = strip->next) {
-               /* fix strip's action */
-               if (strip->act) {
-                       any_removed |= fcurves_path_remove_fix(prefix, &strip->act->curves);
-               }
+  /* recursively check strips, fixing only actions... */
+  for (strip = strips->first; strip; strip = strip->next) {
+    /* fix strip's action */
+    if (strip->act) {
+      any_removed |= fcurves_path_remove_fix(prefix, &strip->act->curves);
+    }
 
-               /* check sub-strips (if metas) */
-               any_removed |= nlastrips_path_remove_fix(prefix, &strip->strips);
-       }
-       return any_removed;
+    /* check sub-strips (if metas) */
+    any_removed |= nlastrips_path_remove_fix(prefix, &strip->strips);
+  }
+  return any_removed;
 }
 
 bool BKE_animdata_fix_paths_remove(ID *id, const char *prefix)
 {
-       /* Only some ID-blocks have this info for now, so we cast the
-        * types that do to be of type IdAdtTemplate
-        */
-       if (!id_can_have_animdata(id)) {
-               return false;
-       }
-       bool any_removed = false;
-       IdAdtTemplate *iat = (IdAdtTemplate *)id;
-       AnimData *adt = iat->adt;
-       /* check if there's any AnimData to start with */
-       if (adt) {
-               /* free fcurves */
-               if (adt->action != NULL) {
-                       any_removed |= fcurves_path_remove_fix(prefix, &adt->action->curves);
-               }
-               if (adt->tmpact != NULL) {
-                       any_removed |= fcurves_path_remove_fix(prefix, &adt->tmpact->curves);
-               }
-               /* free drivers - stored as a list of F-Curves */
-               any_removed |= fcurves_path_remove_fix(prefix, &adt->drivers);
-               /* NLA Data - Animation Data for Strips */
-               for (NlaTrack *nlt = adt->nla_tracks.first; nlt; nlt = nlt->next) {
-                       any_removed |= nlastrips_path_remove_fix(prefix, &nlt->strips);
-               }
-       }
-       return any_removed;
+  /* Only some ID-blocks have this info for now, so we cast the
+   * types that do to be of type IdAdtTemplate
+   */
+  if (!id_can_have_animdata(id)) {
+    return false;
+  }
+  bool any_removed = false;
+  IdAdtTemplate *iat = (IdAdtTemplate *)id;
+  AnimData *adt = iat->adt;
+  /* check if there's any AnimData to start with */
+  if (adt) {
+    /* free fcurves */
+    if (adt->action != NULL) {
+      any_removed |= fcurves_path_remove_fix(prefix, &adt->action->curves);
+    }
+    if (adt->tmpact != NULL) {
+      any_removed |= fcurves_path_remove_fix(prefix, &adt->tmpact->curves);
+    }
+    /* free drivers - stored as a list of F-Curves */
+    any_removed |= fcurves_path_remove_fix(prefix, &adt->drivers);
+    /* NLA Data - Animation Data for Strips */
+    for (NlaTrack *nlt = adt->nla_tracks.first; nlt; nlt = nlt->next) {
+      any_removed |= nlastrips_path_remove_fix(prefix, &nlt->strips);
+    }
+  }
+  return any_removed;
 }
 
 /* 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 */
+  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)
+static void fcurves_apply_cb(ID *id,
+                             ListBase *fcurves,
+                             ID_FCurve_Edit_Callback func,
+                             void *user_data)
 {
-       FCurve *fcu;
+  FCurve *fcu;
 
-       for (fcu = fcurves->first; fcu; fcu = fcu->next) {
-               func(id, fcu, user_data);
-       }
+  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;
+  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);
-               }
+  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);
-       }
+    /* 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, void *wrapper_data)
 {
-       AllFCurvesCbWrapper *wrapper = wrapper_data;
-       NlaTrack *nlt;
+  AllFCurvesCbWrapper *wrapper = wrapper_data;
+  NlaTrack *nlt;
 
-       if (adt->action) {
-               fcurves_apply_cb(id, &adt->action->curves, wrapper->func, wrapper->user_data);
-       }
+  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);
-       }
+  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);
+  /* 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);
-       }
+  /* 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);
+  }
+}
+
+void BKE_fcurves_id_cb(ID *id, ID_FCurve_Edit_Callback func, void *user_data)
+{
+  AnimData *adt = BKE_animdata_from_id(id);
+  if (adt != NULL) {
+    AllFCurvesCbWrapper wrapper = {func, user_data};
+    adt_apply_all_fcurves_cb(id, adt, &wrapper);
+  }
 }
 
 /* apply the given callback function on all F-Curves attached to data in main database */
 void BKE_fcurves_main_cb(Main *bmain, 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};
+  /* 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(bmain, adt_apply_all_fcurves_cb, &wrapper);
+  /* Use the AnimData-based function so that we don't have to reimplement all that stuff */
+  BKE_animdata_main_cb(bmain, adt_apply_all_fcurves_cb, &wrapper);
 }
 
-
 /* Whole Database Ops -------------------------------------------- */
 
 /* apply the given callback function on all data in main database */
 void BKE_animdata_main_cb(Main *bmain, ID_AnimData_Edit_Callback func, void *user_data)
 {
-       ID *id;
+  ID *id;
 
-       /* standard data version */
+  /* standard data version */
 #define ANIMDATA_IDS_CB(first) \
-       for (id = first; id; id = id->next) { \
-               AnimData *adt = BKE_animdata_from_id(id); \
-               if (adt) func(id, adt, user_data); \
-       } (void)0
-
-       /* "embedded" nodetree cases (i.e. scene/material/texture->nodetree) */
+  for (id = first; id; id = id->next) { \
+    AnimData *adt = BKE_animdata_from_id(id); \
+    if (adt) \
+      func(id, adt, user_data); \
+  } \
+  (void)0
+
+  /* "embedded" nodetree cases (i.e. scene/material/texture->nodetree) */
 #define ANIMDATA_NODETREE_IDS_CB(first, NtId_Type) \
-       for (id = first; id; id = id->next) { \
-               AnimData *adt = BKE_animdata_from_id(id); \
-               NtId_Type *ntp = (NtId_Type *)id; \
-               if (ntp->nodetree) { \
-                       AnimData *adt2 = BKE_animdata_from_id((ID *)ntp->nodetree); \
-                       if (adt2) func(id, adt2, user_data); \
-               } \
-               if (adt) func(id, adt, user_data); \
-       } (void)0
+  for (id = first; id; id = id->next) { \
+    AnimData *adt = BKE_animdata_from_id(id); \
+    NtId_Type *ntp = (NtId_Type *)id; \
+    if (ntp->nodetree) { \
+      AnimData *adt2 = BKE_animdata_from_id((ID *)ntp->nodetree); \
+      if (adt2) \
+        func(id, adt2, user_data); \
+    } \
+    if (adt) \
+      func(id, adt, user_data); \
+  } \
+  (void)0
 
-       /* nodes */
-       ANIMDATA_IDS_CB(bmain->nodetree.first);
+  /* nodes */
+  ANIMDATA_IDS_CB(bmain->nodetrees.first);
 
-       /* textures */
-       ANIMDATA_NODETREE_IDS_CB(bmain->tex.first, Tex);
+  /* textures */
+  ANIMDATA_NODETREE_IDS_CB(bmain->textures.first, Tex);
 
-       /* lamps */
-       ANIMDATA_NODETREE_IDS_CB(bmain->lamp.first, Lamp);
+  /* lights */
+  ANIMDATA_NODETREE_IDS_CB(bmain->lights.first, Light);
 
-       /* materials */
-       ANIMDATA_NODETREE_IDS_CB(bmain->mat.first, Material);
+  /* materials */
+  ANIMDATA_NODETREE_IDS_CB(bmain->materials.first, Material);
 
-       /* cameras */
-       ANIMDATA_IDS_CB(bmain->camera.first);
+  /* cameras */
+  ANIMDATA_IDS_CB(bmain->cameras.first);
 
-       /* shapekeys */
-       ANIMDATA_IDS_CB(bmain->key.first);
+  /* shapekeys */
+  ANIMDATA_IDS_CB(bmain->shapekeys.first);
 
-       /* metaballs */
-       ANIMDATA_IDS_CB(bmain->mball.first);
+  /* metaballs */
+  ANIMDATA_IDS_CB(bmain->metaballs.first);
 
-       /* curves */
-       ANIMDATA_IDS_CB(bmain->curve.first);
+  /* curves */
+  ANIMDATA_IDS_CB(bmain->curves.first);
 
-       /* armatures */
-       ANIMDATA_IDS_CB(bmain->armature.first);
+  /* armatures */
+  ANIMDATA_IDS_CB(bmain->armatures.first);
 
-       /* lattices */
-       ANIMDATA_IDS_CB(bmain->latt.first);
+  /* lattices */
+  ANIMDATA_IDS_CB(bmain->lattices.first);
 
-       /* meshes */
-       ANIMDATA_IDS_CB(bmain->mesh.first);
+  /* meshes */
+  ANIMDATA_IDS_CB(bmain->meshes.first);
 
-       /* particles */
-       ANIMDATA_IDS_CB(bmain->particle.first);
+  /* particles */
+  ANIMDATA_IDS_CB(bmain->particles.first);
 
-       /* speakers */
-       ANIMDATA_IDS_CB(bmain->speaker.first);
+  /* speakers */
+  ANIMDATA_IDS_CB(bmain->speakers.first);
 
-       /* movie clips */
-       ANIMDATA_IDS_CB(bmain->movieclip.first);
+  /* movie clips */
+  ANIMDATA_IDS_CB(bmain->movieclips.first);
 
-       /* objects */
-       ANIMDATA_IDS_CB(bmain->object.first);
+  /* objects */
+  ANIMDATA_IDS_CB(bmain->objects.first);
 
-       /* masks */
-       ANIMDATA_IDS_CB(bmain->mask.first);
+  /* masks */
+  ANIMDATA_IDS_CB(bmain->masks.first);
 
-       /* worlds */
-       ANIMDATA_NODETREE_IDS_CB(bmain->world.first, World);
+  /* worlds */
+  ANIMDATA_NODETREE_IDS_CB(bmain->worlds.first, World);
 
-       /* scenes */
-       ANIMDATA_NODETREE_IDS_CB(bmain->scene.first, Scene);
+  /* scenes */
+  ANIMDATA_NODETREE_IDS_CB(bmain->scenes.first, Scene);
 
-       /* line styles */
-       ANIMDATA_IDS_CB(bmain->linestyle.first);
+  /* line styles */
+  ANIMDATA_IDS_CB(bmain->linestyles.first);
 
-       /* grease pencil */
-       ANIMDATA_IDS_CB(bmain->gpencil.first);
+  /* grease pencil */
+  ANIMDATA_IDS_CB(bmain->gpencils.first);
 
-       /* palettes */
-       ANIMDATA_IDS_CB(bmain->palettes.first);
+  /* palettes */
+  ANIMDATA_IDS_CB(bmain->palettes.first);
 
-       /* cache files */
-       ANIMDATA_IDS_CB(bmain->cachefiles.first);
+  /* cache files */
+  ANIMDATA_IDS_CB(bmain->cachefiles.first);
 }
 
 /* Fix all RNA-Paths throughout the database (directly access the Global.main version)
@@ -1197,95 +1300,101 @@ void BKE_animdata_main_cb(Main *bmain, ID_AnimData_Edit_Callback func, void *use
  *      i.e. pose.bones["Bone"]
  */
 /* TODO: use BKE_animdata_main_cb for looping over all data  */
-void BKE_animdata_fix_paths_rename_all(ID *ref_id, const char *prefix, const char *oldName, const char *newName)
-{
-       Main *bmain = G.main;  /* XXX UGLY! */
-       ID *id;
-
-       /* macro for less typing
-        * - whether animdata exists is checked for by the main renaming callback, though taking
-        *   this outside of the function may make things slightly faster?
-        */
+void BKE_animdata_fix_paths_rename_all(ID *ref_id,
+                                       const char *prefix,
+                                       const char *oldName,
+                                       const char *newName)
+{
+  Main *bmain = G.main; /* XXX UGLY! */
+  ID *id;
+
+  /* macro for less typing
+   * - whether animdata exists is checked for by the main renaming callback, though taking
+   *   this outside of the function may make things slightly faster?
+   */
 #define RENAMEFIX_ANIM_IDS(first) \
-       for (id = first; id; id = id->next) { \
-               AnimData *adt = BKE_animdata_from_id(id); \
-               BKE_animdata_fix_paths_rename(id, adt, ref_id, prefix, oldName, newName, 0, 0, 1); \
-       } (void)0
+  for (id = first; id; id = id->next) { \
+    AnimData *adt = BKE_animdata_from_id(id); \
+    BKE_animdata_fix_paths_rename(id, adt, ref_id, prefix, oldName, newName, 0, 0, 1); \
+  } \
+  (void)0
 
-       /* another version of this macro for nodetrees */
+  /* another version of this macro for nodetrees */
 #define RENAMEFIX_ANIM_NODETREE_IDS(first, NtId_Type) \
-       for (id = first; id; id = id->next) { \
-               AnimData *adt = BKE_animdata_from_id(id); \
-               NtId_Type *ntp = (NtId_Type *)id; \
-               if (ntp->nodetree) { \
-                       AnimData *adt2 = BKE_animdata_from_id((ID *)ntp->nodetree); \
-                       BKE_animdata_fix_paths_rename((ID *)ntp->nodetree, adt2, ref_id, prefix, oldName, newName, 0, 0, 1); \
-               } \
-               BKE_animdata_fix_paths_rename(id, adt, ref_id, prefix, oldName, newName, 0, 0, 1); \
-       } (void)0
+  for (id = first; id; id = id->next) { \
+    AnimData *adt = BKE_animdata_from_id(id); \
+    NtId_Type *ntp = (NtId_Type *)id; \
+    if (ntp->nodetree) { \
+      AnimData *adt2 = BKE_animdata_from_id((ID *)ntp->nodetree); \
+      BKE_animdata_fix_paths_rename( \
+          (ID *)ntp->nodetree, adt2, ref_id, prefix, oldName, newName, 0, 0, 1); \
+    } \
+    BKE_animdata_fix_paths_rename(id, adt, ref_id, prefix, oldName, newName, 0, 0, 1); \
+  } \
+  (void)0
 
-       /* nodes */
-       RENAMEFIX_ANIM_IDS(bmain->nodetree.first);
+  /* nodes */
+  RENAMEFIX_ANIM_IDS(bmain->nodetrees.first);
 
-       /* textures */
-       RENAMEFIX_ANIM_NODETREE_IDS(bmain->tex.first, Tex);
+  /* textures */
+  RENAMEFIX_ANIM_NODETREE_IDS(bmain->textures.first, Tex);
 
-       /* lamps */
-       RENAMEFIX_ANIM_NODETREE_IDS(bmain->lamp.first, Lamp);
+  /* lights */
+  RENAMEFIX_ANIM_NODETREE_IDS(bmain->lights.first, Light);
 
-       /* materials */
-       RENAMEFIX_ANIM_NODETREE_IDS(bmain->mat.first, Material);
+  /* materials */
+  RENAMEFIX_ANIM_NODETREE_IDS(bmain->materials.first, Material);
 
-       /* cameras */
-       RENAMEFIX_ANIM_IDS(bmain->camera.first);
+  /* cameras */
+  RENAMEFIX_ANIM_IDS(bmain->cameras.first);
 
-       /* shapekeys */
-       RENAMEFIX_ANIM_IDS(bmain->key.first);
+  /* shapekeys */
+  RENAMEFIX_ANIM_IDS(bmain->shapekeys.first);
 
-       /* metaballs */
-       RENAMEFIX_ANIM_IDS(bmain->mball.first);
+  /* metaballs */
+  RENAMEFIX_ANIM_IDS(bmain->metaballs.first);
 
-       /* curves */
-       RENAMEFIX_ANIM_IDS(bmain->curve.first);
+  /* curves */
+  RENAMEFIX_ANIM_IDS(bmain->curves.first);
 
-       /* armatures */
-       RENAMEFIX_ANIM_IDS(bmain->armature.first);
+  /* armatures */
+  RENAMEFIX_ANIM_IDS(bmain->armatures.first);
 
-       /* lattices */
-       RENAMEFIX_ANIM_IDS(bmain->latt.first);
+  /* lattices */
+  RENAMEFIX_ANIM_IDS(bmain->lattices.first);
 
-       /* meshes */
-       RENAMEFIX_ANIM_IDS(bmain->mesh.first);
+  /* meshes */
+  RENAMEFIX_ANIM_IDS(bmain->meshes.first);
 
-       /* particles */
-       RENAMEFIX_ANIM_IDS(bmain->particle.first);
+  /* particles */
+  RENAMEFIX_ANIM_IDS(bmain->particles.first);
 
-       /* speakers */
-       RENAMEFIX_ANIM_IDS(bmain->speaker.first);
+  /* speakers */
+  RENAMEFIX_ANIM_IDS(bmain->speakers.first);
 
-       /* movie clips */
-       RENAMEFIX_ANIM_IDS(bmain->movieclip.first);
+  /* movie clips */
+  RENAMEFIX_ANIM_IDS(bmain->movieclips.first);
 
-       /* objects */
-       RENAMEFIX_ANIM_IDS(bmain->object.first);
+  /* objects */
+  RENAMEFIX_ANIM_IDS(bmain->objects.first);
 
-       /* masks */
-       RENAMEFIX_ANIM_IDS(bmain->mask.first);
+  /* masks */
+  RENAMEFIX_ANIM_IDS(bmain->masks.first);
 
-       /* worlds */
-       RENAMEFIX_ANIM_NODETREE_IDS(bmain->world.first, World);
+  /* worlds */
+  RENAMEFIX_ANIM_NODETREE_IDS(bmain->worlds.first, World);
 
-       /* linestyles */
-       RENAMEFIX_ANIM_IDS(bmain->linestyle.first);
+  /* linestyles */
+  RENAMEFIX_ANIM_IDS(bmain->linestyles.first);
 
-       /* grease pencil */
-       RENAMEFIX_ANIM_IDS(bmain->gpencil.first);
+  /* grease pencil */
+  RENAMEFIX_ANIM_IDS(bmain->gpencils.first);
 
-       /* cache files */
-       RENAMEFIX_ANIM_IDS(bmain->cachefiles.first);
+  /* cache files */
+  RENAMEFIX_ANIM_IDS(bmain->cachefiles.first);
 
-       /* scenes */
-       RENAMEFIX_ANIM_NODETREE_IDS(bmain->scene.first, Scene);
+  /* scenes */
+  RENAMEFIX_ANIM_NODETREE_IDS(bmain->scenes.first, Scene);
 }
 
 /* *********************************** */
@@ -1295,161 +1404,188 @@ void BKE_animdata_fix_paths_rename_all(ID *ref_id, const char *prefix, const cha
 
 /* Find the first path that matches the given criteria */
 /* TODO: do we want some method to perform partial matches too? */
-KS_Path *BKE_keyingset_find_path(KeyingSet *ks, ID *id, const char group_name[], const char rna_path[], int array_index, int UNUSED(group_mode))
-{
-       KS_Path *ksp;
-
-       /* sanity checks */
-       if (ELEM(NULL, ks, rna_path, id))
-               return NULL;
-
-       /* loop over paths in the current KeyingSet, finding the first one where all settings match
-        * (i.e. the first one where none of the checks fail and equal 0)
-        */
-       for (ksp = ks->paths.first; ksp; ksp = ksp->next) {
-               short eq_id = 1, eq_path = 1, eq_index = 1, eq_group = 1;
-
-               /* id */
-               if (id != ksp->id)
-                       eq_id = 0;
-
-               /* path */
-               if ((ksp->rna_path == NULL) || !STREQ(rna_path, ksp->rna_path))
-                       eq_path = 0;
-
-               /* index - need to compare whole-array setting too... */
-               if (ksp->array_index != array_index)
-                       eq_index = 0;
-
-               /* group */
-               if (group_name) {
-                       /* FIXME: these checks need to be coded... for now, it's not too important though */
-               }
-
-               /* if all aspects are ok, return */
-               if (eq_id && eq_path && eq_index && eq_group)
-                       return ksp;
-       }
-
-       /* none found */
-       return NULL;
+KS_Path *BKE_keyingset_find_path(KeyingSet *ks,
+                                 ID *id,
+                                 const char group_name[],
+                                 const char rna_path[],
+                                 int array_index,
+                                 int UNUSED(group_mode))
+{
+  KS_Path *ksp;
+
+  /* sanity checks */
+  if (ELEM(NULL, ks, rna_path, id)) {
+    return NULL;
+  }
+
+  /* loop over paths in the current KeyingSet, finding the first one where all settings match
+   * (i.e. the first one where none of the checks fail and equal 0)
+   */
+  for (ksp = ks->paths.first; ksp; ksp = ksp->next) {
+    short eq_id = 1, eq_path = 1, eq_index = 1, eq_group = 1;
+
+    /* id */
+    if (id != ksp->id) {
+      eq_id = 0;
+    }
+
+    /* path */
+    if ((ksp->rna_path == NULL) || !STREQ(rna_path, ksp->rna_path)) {
+      eq_path = 0;
+    }
+
+    /* index - need to compare whole-array setting too... */
+    if (ksp->array_index != array_index) {
+      eq_index = 0;
+    }
+
+    /* group */
+    if (group_name) {
+      /* FIXME: these checks need to be coded... for now, it's not too important though */
+    }
+
+    /* if all aspects are ok, return */
+    if (eq_id && eq_path && eq_index && eq_group) {
+      return ksp;
+    }
+  }
+
+  /* none found */
+  return NULL;
 }
 
 /* Defining Tools --------------------------- */
 
 /* Used to create a new 'custom' KeyingSet for the user, that will be automatically added to the stack */
-KeyingSet *BKE_keyingset_add(ListBase *list, const char idname[], const char name[], short flag, short keyingflag)
+KeyingSet *BKE_keyingset_add(
+    ListBase *list, const char idname[], const char name[], short flag, short keyingflag)
 {
-       KeyingSet *ks;
+  KeyingSet *ks;
 
-       /* allocate new KeyingSet */
-       ks = MEM_callocN(sizeof(KeyingSet), "KeyingSet");
+  /* allocate new KeyingSet */
+  ks = MEM_callocN(sizeof(KeyingSet), "KeyingSet");
 
-       BLI_strncpy(ks->idname, (idname) ? idname : (name) ? name     : DATA_("KeyingSet"),  sizeof(ks->idname));
-       BLI_strncpy(ks->name,   (name) ? name     : (idname) ? idname : DATA_("Keying Set"), sizeof(ks->name));
+  BLI_strncpy(
+      ks->idname, (idname) ? idname : (name) ? name : DATA_("KeyingSet"), sizeof(ks->idname));
+  BLI_strncpy(ks->name, (name) ? name : (idname) ? idname : DATA_("Keying Set"), sizeof(ks->name));
 
-       ks->flag = flag;
-       ks->keyingflag = keyingflag;
-       ks->keyingoverride = keyingflag; /* NOTE: assume that if one is set one way, the other should be too, so that it'll work */
+  ks->flag = flag;
+  ks->keyingflag = keyingflag;
+  ks->keyingoverride =
+      keyingflag; /* NOTE: assume that if one is set one way, the other should be too, so that it'll work */
 
-       /* add KeyingSet to list */
-       BLI_addtail(list, ks);
+  /* add KeyingSet to list */
+  BLI_addtail(list, ks);
 
-       /* Make sure KeyingSet has a unique idname */
-       BLI_uniquename(list, ks, DATA_("KeyingSet"), '.', offsetof(KeyingSet, idname), sizeof(ks->idname));
+  /* Make sure KeyingSet has a unique idname */
+  BLI_uniquename(
+      list, ks, DATA_("KeyingSet"), '.', offsetof(KeyingSet, idname), sizeof(ks->idname));
 
-       /* Make sure KeyingSet has a unique label (this helps with identification) */
-       BLI_uniquename(list, ks, DATA_("Keying Set"), '.', offsetof(KeyingSet, name), sizeof(ks->name));
+  /* Make sure KeyingSet has a unique label (this helps with identification) */
+  BLI_uniquename(list, ks, DATA_("Keying Set"), '.', offsetof(KeyingSet, name), sizeof(ks->name));
 
-       /* return new KeyingSet for further editing */
-       return ks;
+  /* return new KeyingSet for further editing */
+  return ks;
 }
 
 /* Add a path to a KeyingSet. Nothing is returned for now...
  * Checks are performed to ensure that destination is appropriate for the KeyingSet in question
  */
-KS_Path *BKE_keyingset_add_path(KeyingSet *ks, ID *id, const char group_name[], const char rna_path[], int array_index, short flag, short groupmode)
-{
-       KS_Path *ksp;
-
-       /* sanity checks */
-       if (ELEM(NULL, ks, rna_path)) {
-               CLOG_ERROR(&LOG, "no Keying Set and/or RNA Path to add path with");
-               return NULL;
-       }
-
-       /* ID is required for all types of KeyingSets */
-       if (id == NULL) {
-               CLOG_ERROR(&LOG, "No ID provided for Keying Set Path");
-               return NULL;
-       }
-
-       /* don't add if there is already a matching KS_Path in the KeyingSet */
-       if (BKE_keyingset_find_path(ks, id, group_name, rna_path, array_index, groupmode)) {
-               if (G.debug & G_DEBUG)
-                       CLOG_ERROR(&LOG, "destination already exists in Keying Set");
-               return NULL;
-       }
-
-       /* allocate a new KeyingSet Path */
-       ksp = MEM_callocN(sizeof(KS_Path), "KeyingSet Path");
-
-       /* just store absolute info */
-       ksp->id = id;
-       if (group_name)
-               BLI_strncpy(ksp->group, group_name, sizeof(ksp->group));
-       else
-               ksp->group[0] = '\0';
-
-       /* store additional info for relative paths (just in case user makes the set relative) */
-       if (id)
-               ksp->idtype = GS(id->name);
-
-       /* just copy path info */
-       /* TODO: should array index be checked too? */
-       ksp->rna_path = BLI_strdup(rna_path);
-       ksp->array_index = array_index;
-
-       /* store flags */
-       ksp->flag = flag;
-       ksp->groupmode = groupmode;
-
-       /* add KeyingSet path to KeyingSet */
-       BLI_addtail(&ks->paths, ksp);
-
-       /* return this path */
-       return ksp;
+KS_Path *BKE_keyingset_add_path(KeyingSet *ks,
+                                ID *id,
+                                const char group_name[],
+                                const char rna_path[],
+                                int array_index,
+                                short flag,
+                                short groupmode)
+{
+  KS_Path *ksp;
+
+  /* sanity checks */
+  if (ELEM(NULL, ks, rna_path)) {
+    CLOG_ERROR(&LOG, "no Keying Set and/or RNA Path to add path with");
+    return NULL;
+  }
+
+  /* ID is required for all types of KeyingSets */
+  if (id == NULL) {
+    CLOG_ERROR(&LOG, "No ID provided for Keying Set Path");
+    return NULL;
+  }
+
+  /* don't add if there is already a matching KS_Path in the KeyingSet */
+  if (BKE_keyingset_find_path(ks, id, group_name, rna_path, array_index, groupmode)) {
+    if (G.debug & G_DEBUG) {
+      CLOG_ERROR(&LOG, "destination already exists in Keying Set");
+    }
+    return NULL;
+  }
+
+  /* allocate a new KeyingSet Path */
+  ksp = MEM_callocN(sizeof(KS_Path), "KeyingSet Path");
+
+  /* just store absolute info */
+  ksp->id = id;
+  if (group_name) {
+    BLI_strncpy(ksp->group, group_name, sizeof(ksp->group));
+  }
+  else {
+    ksp->group[0] = '\0';
+  }
+
+  /* store additional info for relative paths (just in case user makes the set relative) */
+  if (id) {
+    ksp->idtype = GS(id->name);
+  }
+
+  /* just copy path info */
+  /* TODO: should array index be checked too? */
+  ksp->rna_path = BLI_strdup(rna_path);
+  ksp->array_index = array_index;
+
+  /* store flags */
+  ksp->flag = flag;
+  ksp->groupmode = groupmode;
+
+  /* add KeyingSet path to KeyingSet */
+  BLI_addtail(&ks->paths, ksp);
+
+  /* return this path */
+  return ksp;
 }
 
 /* Free the given Keying Set path */
 void BKE_keyingset_free_path(KeyingSet *ks, KS_Path *ksp)
 {
-       /* sanity check */
-       if (ELEM(NULL, ks, ksp))
-               return;
+  /* sanity check */
+  if (ELEM(NULL, ks, ksp)) {
+    return;
+  }
 
-       /* free RNA-path info */
-       if (ksp->rna_path)
-               MEM_freeN(ksp->rna_path);
+  /* free RNA-path info */
+  if (ksp->rna_path) {
+    MEM_freeN(ksp->rna_path);
+  }
 
-       /* free path itself */
-       BLI_freelinkN(&ks->paths, ksp);
+  /* free path itself */
+  BLI_freelinkN(&ks->paths, ksp);
 }
 
 /* Copy all KeyingSets in the given list */
 void BKE_keyingsets_copy(ListBase *newlist, const ListBase *list)
 {
-       KeyingSet *ksn;
-       KS_Path *kspn;
+  KeyingSet *ksn;
+  KS_Path *kspn;
 
-       BLI_duplicatelist(newlist, list);
+  BLI_duplicatelist(newlist, list);
 
-       for (ksn = newlist->first; ksn; ksn = ksn->next) {
-               BLI_duplicatelist(&ksn->paths, &ksn->paths);
+  for (ksn = newlist->first; ksn; ksn = ksn->next) {
+    BLI_duplicatelist(&ksn->paths, &ksn->paths);
 
-               for (kspn = ksn->paths.first; kspn; kspn = kspn->next)
-                       kspn->rna_path = MEM_dupallocN(kspn->rna_path);
-       }
+    for (kspn = ksn->paths.first; kspn; kspn = kspn->next) {
+      kspn->rna_path = MEM_dupallocN(kspn->rna_path);
+    }
+  }
 }
 
 /* Freeing Tools --------------------------- */
@@ -1457,289 +1593,288 @@ void BKE_keyingsets_copy(ListBase *newlist, const ListBase *list)
 /* Free data for KeyingSet but not set itself */
 void BKE_keyingset_free(KeyingSet *ks)
 {
-       KS_Path *ksp, *kspn;
+  KS_Path *ksp, *kspn;
 
-       /* sanity check */
-       if (ks == NULL)
-               return;
+  /* sanity check */
+  if (ks == NULL) {
+    return;
+  }
 
-       /* free each path as we go to avoid looping twice */
-       for (ksp = ks->paths.first; ksp; ksp = kspn) {
-               kspn = ksp->next;
-               BKE_keyingset_free_path(ks, ksp);
-       }
+  /* free each path as we go to avoid looping twice */
+  for (ksp = ks->paths.first; ksp; ksp = kspn) {
+    kspn = ksp->next;
+    BKE_keyingset_free_path(ks, ksp);
+  }
 }
 
 /* Free all the KeyingSets in the given list */
 void BKE_keyingsets_free(ListBase *list)
 {
-       KeyingSet *ks, *ksn;
+  KeyingSet *ks, *ksn;
 
-       /* sanity check */
-       if (list == NULL)
-               return;
+  /* sanity check */
+  if (list == NULL) {
+    return;
+  }
 
-       /* loop over KeyingSets freeing them
-        * - BKE_keyingset_free() doesn't free the set itself, but it frees its sub-data
-        */
-       for (ks = list->first; ks; ks = ksn) {
-               ksn = ks->next;
-               BKE_keyingset_free(ks);
-               BLI_freelinkN(list, ks);
-       }
+  /* loop over KeyingSets freeing them
+   * - BKE_keyingset_free() doesn't free the set itself, but it frees its sub-data
+   */
+  for (ks = list->first; ks; ks = ksn) {
+    ksn = ks->next;
+    BKE_keyingset_free(ks);
+    BLI_freelinkN(list, ks);
+  }
 }
 
 /* ***************************************** */
 /* Evaluation Data-Setting Backend */
 
-static bool animsys_store_rna_setting(
-        PointerRNA *ptr,
-        /* typically 'fcu->rna_path', 'fcu->array_index' */
-        const char *rna_path, const int array_index,
-        PathResolvedRNA *r_result)
-{
-       bool success = false;
-       const char *path = rna_path;
-
-       /* write value to setting */
-       if (path) {
-               /* get property to write to */
-               if (RNA_path_resolve_property(ptr, path, &r_result->ptr, &r_result->prop)) {
-                       if ((ptr->id.data == NULL) || RNA_property_animateable(&r_result->ptr, r_result->prop)) {
-                               int array_len = RNA_property_array_length(&r_result->ptr, r_result->prop);
-
-                               if (array_len && array_index >= array_len) {
-                                       if (G.debug & G_DEBUG) {
-                                               CLOG_WARN(&LOG, "Animato: Invalid array index. ID = '%s',  '%s[%d]', array length is %d",
-                                                         (ptr->id.data) ? (((ID *)ptr->id.data)->name + 2) : "<No ID>",
-                                                         path, array_index, array_len - 1);
-                                       }
-                               }
-                               else {
-                                       r_result->prop_index = array_len ? array_index : -1;
-                                       success = true;
-                               }
-                       }
-               }
-               else {
-                       /* failed to get path */
-                       /* XXX don't tag as failed yet though, as there are some legit situations (Action Constraint)
-                        * where some channels will not exist, but shouldn't lock up Action */
-                       if (G.debug & G_DEBUG) {
-                               CLOG_WARN(&LOG, "Animato: Invalid path. ID = '%s',  '%s[%d]'",
-                                         (ptr->id.data) ? (((ID *)ptr->id.data)->name + 2) : "<No ID>",
-                                         path, array_index);
-                       }
-               }
-       }
-
-       return success;
+static bool animsys_store_rna_setting(PointerRNA *ptr,
+                                      /* typically 'fcu->rna_path', 'fcu->array_index' */
+                                      const char *rna_path,
+                                      const int array_index,
+                                      PathResolvedRNA *r_result)
+{
+  bool success = false;
+  const char *path = rna_path;
+
+  /* write value to setting */
+  if (path) {
+    /* get property to write to */
+    if (RNA_path_resolve_property(ptr, path, &r_result->ptr, &r_result->prop)) {
+      if ((ptr->id.data == NULL) || RNA_property_animateable(&r_result->ptr, r_result->prop)) {
+        int array_len = RNA_property_array_length(&r_result->ptr, r_result->prop);
+
+        if (array_len && array_index >= array_len) {
+          if (G.debug & G_DEBUG) {
+            CLOG_WARN(&LOG,
+                      "Animato: Invalid array index. ID = '%s',  '%s[%d]', array length is %d",
+                      (ptr->id.data) ? (((ID *)ptr->id.data)->name + 2) : "<No ID>",
+                      path,
+                      array_index,
+                      array_len - 1);
+          }
+        }
+        else {
+          r_result->prop_index = array_len ? array_index : -1;
+          success = true;
+        }
+      }
+    }
+    else {
+      /* failed to get path */
+      /* XXX don't tag as failed yet though, as there are some legit situations (Action Constraint)
+       * where some channels will not exist, but shouldn't lock up Action */
+      if (G.debug & G_DEBUG) {
+        CLOG_WARN(&LOG,
+                  "Animato: Invalid path. ID = '%s',  '%s[%d]'",
+                  (ptr->id.data) ? (((ID *)ptr->id.data)->name + 2) : "<No ID>",
+                  path,
+                  array_index);
+      }
+    }
+  }
+
+  return success;
 }
 
-
 /* less than 1.0 evaluates to false, use epsilon to avoid float error */
 #define ANIMSYS_FLOAT_AS_BOOL(value) ((value) > ((1.0f - FLT_EPSILON)))
 
 static bool animsys_read_rna_setting(PathResolvedRNA *anim_rna, float *r_value)
 {
-       PropertyRNA *prop = anim_rna->prop;
-       PointerRNA *ptr = &anim_rna->ptr;
-       int array_index = anim_rna->prop_index;
-       float orig_value;
-
-       /* caller must ensure this is animatable */
-       BLI_assert(RNA_property_animateable(ptr, prop) || ptr->id.data == NULL);
-
-       switch (RNA_property_type(prop)) {
-               case PROP_BOOLEAN:
-               {
-                       if (array_index != -1) {
-                               const int orig_value_coerce = RNA_property_boolean_get_index(ptr, prop, array_index);
-                               orig_value = (float)orig_value_coerce;
-                       }
-                       else {
-                               const int orig_value_coerce = RNA_property_boolean_get(ptr, prop);
-                               orig_value = (float)orig_value_coerce;
-                       }
-                       break;
-               }
-               case PROP_INT:
-               {
-                       if (array_index != -1) {
-                               const int orig_value_coerce = RNA_property_int_get_index(ptr, prop, array_index);
-                               orig_value = (float)orig_value_coerce;
-                       }
-                       else {
-                               const int orig_value_coerce = RNA_property_int_get(ptr, prop);
-                               orig_value = (float)orig_value_coerce;
-                       }
-                       break;
-               }
-               case PROP_FLOAT:
-               {
-                       if (array_index != -1) {
-                               const float orig_value_coerce = RNA_property_float_get_index(ptr, prop, array_index);
-                               orig_value = (float)orig_value_coerce;
-                       }
-                       else {
-                               const float orig_value_coerce = RNA_property_float_get(ptr, prop);
-                               orig_value = (float)orig_value_coerce;
-                       }
-                       break;
-               }
-               case PROP_ENUM:
-               {
-                       const int orig_value_coerce = RNA_property_enum_get(ptr, prop);
-                       orig_value = (float)orig_value_coerce;
-                       break;
-               }
-               default:
-                       /* nothing can be done here... so it is unsuccessful? */
-                       return false;
-       }
-
-       if (r_value != NULL) {
-               *r_value = orig_value;
-       }
-
-       /* successful */
-       return true;
+  PropertyRNA *prop = anim_rna->prop;
+  PointerRNA *ptr = &anim_rna->ptr;
+  int array_index = anim_rna->prop_index;
+  float orig_value;
+
+  /* caller must ensure this is animatable */
+  BLI_assert(RNA_property_animateable(ptr, prop) || ptr->id.data == NULL);
+
+  switch (RNA_property_type(prop)) {
+    case PROP_BOOLEAN: {
+      if (array_index != -1) {
+        const int orig_value_coerce = RNA_property_boolean_get_index(ptr, prop, array_index);
+        orig_value = (float)orig_value_coerce;
+      }
+      else {
+        const int orig_value_coerce = RNA_property_boolean_get(ptr, prop);
+        orig_value = (float)orig_value_coerce;
+      }
+      break;
+    }
+    case PROP_INT: {
+      if (array_index != -1) {
+        const int orig_value_coerce = RNA_property_int_get_index(ptr, prop, array_index);
+        orig_value = (float)orig_value_coerce;
+      }
+      else {
+        const int orig_value_coerce = RNA_property_int_get(ptr, prop);
+        orig_value = (float)orig_value_coerce;
+      }
+      break;
+    }
+    case PROP_FLOAT: {
+      if (array_index != -1) {
+        const float orig_value_coerce = RNA_property_float_get_index(ptr, prop, array_index);
+        orig_value = (float)orig_value_coerce;
+      }
+      else {
+        const float orig_value_coerce = RNA_property_float_get(ptr, prop);
+        orig_value = (float)orig_value_coerce;
+      }
+      break;
+    }
+    case PROP_ENUM: {
+      const int orig_value_coerce = RNA_property_enum_get(ptr, prop);
+      orig_value = (float)orig_value_coerce;
+      break;
+    }
+    default:
+      /* nothing can be done here... so it is unsuccessful? */
+      return false;
+  }
+
+  if (r_value != NULL) {
+    *r_value = orig_value;
+  }
+
+  /* successful */
+  return true;
 }
 
 /* Write the given value to a setting using RNA, and return success */
 static bool animsys_write_rna_setting(PathResolvedRNA *anim_rna, const float value)
 {
-       PropertyRNA *prop = anim_rna->prop;
-       PointerRNA *ptr = &anim_rna->ptr;
-       int array_index = anim_rna->prop_index;
-
-       /* caller must ensure this is animatable */
-       BLI_assert(RNA_property_animateable(ptr, prop) || ptr->id.data == NULL);
-
-       /* Check whether value is new. Otherwise we skip all the updates. */
-       float old_value;
-       if (!animsys_read_rna_setting(anim_rna, &old_value)) {
-               return false;
-       }
-       if (old_value == value) {
-               return true;
-       }
-
-       switch (RNA_property_type(prop)) {
-               case PROP_BOOLEAN:
-               {
-                       const int value_coerce = ANIMSYS_FLOAT_AS_BOOL(value);
-                       if (array_index != -1) {
-                               RNA_property_boolean_set_index(ptr, prop, array_index, value_coerce);
-                       }
-                       else {
-                               RNA_property_boolean_set(ptr, prop, value_coerce);
-                       }
-                       break;
-               }
-               case PROP_INT:
-               {
-                       int value_coerce = (int)value;
-                       RNA_property_int_clamp(ptr, prop, &value_coerce);
-                       if (array_index != -1) {
-                               RNA_property_int_set_index(ptr, prop, array_index, value_coerce);
-                       }
-                       else {
-                               RNA_property_int_set(ptr, prop, value_coerce);
-                       }
-                       break;
-               }
-               case PROP_FLOAT:
-               {
-                       float value_coerce = value;
-                       RNA_property_float_clamp(ptr, prop, &value_coerce);
-                       if (array_index != -1) {
-                               RNA_property_float_set_index(ptr, prop, array_index, value_coerce);
-                       }
-                       else {
-                               RNA_property_float_set(ptr, prop, value_coerce);
-                       }
-                       break;
-               }
-               case PROP_ENUM:
-               {
-                       const int value_coerce = (int)value;
-                       RNA_property_enum_set(ptr, prop, value_coerce);
-                       break;
-               }
-               default:
-                       /* nothing can be done here... so it is unsuccessful? */
-                       return false;
-       }
-
-       /* successful */
-       return true;
+  PropertyRNA *prop = anim_rna->prop;
+  PointerRNA *ptr = &anim_rna->ptr;
+  int array_index = anim_rna->prop_index;
+
+  /* caller must ensure this is animatable */
+  BLI_assert(RNA_property_animateable(ptr, prop) || ptr->id.data == NULL);
+
+  /* Check whether value is new. Otherwise we skip all the updates. */
+  float old_value;
+  if (!animsys_read_rna_setting(anim_rna, &old_value)) {
+    return false;
+  }
+  if (old_value == value) {
+    return true;
+  }
+
+  switch (RNA_property_type(prop)) {
+    case PROP_BOOLEAN: {
+      const int value_coerce = ANIMSYS_FLOAT_AS_BOOL(value);
+      if (array_index != -1) {
+        RNA_property_boolean_set_index(ptr, prop, array_index, value_coerce);
+      }
+      else {
+        RNA_property_boolean_set(ptr, prop, value_coerce);
+      }
+      break;
+    }
+    case PROP_INT: {
+      int value_coerce = (int)value;
+      RNA_property_int_clamp(ptr, prop, &value_coerce);
+      if (array_index != -1) {
+        RNA_property_int_set_index(ptr, prop, array_index, value_coerce);
+      }
+      else {
+        RNA_property_int_set(ptr, prop, value_coerce);
+      }
+      break;
+    }
+    case PROP_FLOAT: {
+      float value_coerce = value;
+      RNA_property_float_clamp(ptr, prop, &value_coerce);
+      if (array_index != -1) {
+        RNA_property_float_set_index(ptr, prop, array_index, value_coerce);
+      }
+      else {
+        RNA_property_float_set(ptr, prop, value_coerce);
+      }
+      break;
+    }
+    case PROP_ENUM: {
+      const int value_coerce = (int)value;
+      RNA_property_enum_set(ptr, prop, value_coerce);
+      break;
+    }
+    default:
+      /* nothing can be done here... so it is unsuccessful? */
+      return false;
+  }
+
+  /* successful */
+  return true;
 }
 
 /* Simple replacement based data-setting of the FCurve using RNA */
 bool BKE_animsys_execute_fcurve(PointerRNA *ptr, FCurve *fcu, float curval)
 {
-       PathResolvedRNA anim_rna;
-       bool ok = false;
-
-       if (animsys_store_rna_setting(ptr, fcu->rna_path, fcu->array_index, &anim_rna)) {
-               ok = animsys_write_rna_setting(&anim_rna, curval);
-       }
-
-       /* return whether we were successful */
-       return ok;
-}
-
-static void animsys_write_orig_anim_rna(
-        PointerRNA *ptr,
-        const char *rna_path,
-        int array_index,
-        float value)
-{
-       /* Pointer is expected to be an ID pointer, if it's not -- we are doomed.
-        *
-        * NOTE: It is possible to have animation data on NLA strip, see T57360.
-        * TODO(sergey): Find solution for those cases.
-        */
-       if (ptr->id.data == NULL) {
-               return;
-       }
-       PointerRNA orig_ptr = *ptr;
-       orig_ptr.id.data = ((ID *)orig_ptr.id.data)->orig_id;
-       orig_ptr.data = orig_ptr.id.data;
-       PathResolvedRNA orig_anim_rna;
-       /* TODO(sergey): Is there a faster way to get anim_rna of original ID? */
-       if (animsys_store_rna_setting(&orig_ptr, rna_path, array_index, &orig_anim_rna)) {
-               animsys_write_rna_setting(&orig_anim_rna, value);
-       }
+  PathResolvedRNA anim_rna;
+  bool ok = false;
+
+  if (animsys_store_rna_setting(ptr, fcu->rna_path, fcu->array_index, &anim_rna)) {
+    ok = animsys_write_rna_setting(&anim_rna, curval);
+  }
+
+  /* return whether we were successful */
+  return ok;
+}
+
+static void animsys_write_orig_anim_rna(PointerRNA *ptr,
+                                        const char *rna_path,
+                                        int array_index,
+                                        float value)
+{
+  /* Pointer is expected to be an ID pointer, if it's not -- we are doomed.
+   *
+   * NOTE: It is possible to have animation data on NLA strip, see T57360.
+   * TODO(sergey): Find solution for those cases.
+   */
+  if (ptr->id.data == NULL) {
+    return;
+  }
+  PointerRNA orig_ptr = *ptr;
+  orig_ptr.id.data = ((ID *)orig_ptr.id.data)->orig_id;
+  orig_ptr.data = orig_ptr.id.data;
+  PathResolvedRNA orig_anim_rna;
+  /* TODO(sergey): Is there a faster way to get anim_rna of original ID? */
+  if (animsys_store_rna_setting(&orig_ptr, rna_path, array_index, &orig_anim_rna)) {
+    animsys_write_rna_setting(&orig_anim_rna, value);
+  }
 }
 
 /* Evaluate all the F-Curves in the given list
  * This performs a set of standard checks. If extra checks are required, separate code should be used
  */
-static void animsys_evaluate_fcurves(
-        Depsgraph *depsgraph, PointerRNA *ptr, ListBase *list, float ctime)
-{
-       const bool is_active_depsgraph = DEG_is_active(depsgraph);
-       /* Calculate then execute each curve. */
-       for (FCurve *fcu = list->first; fcu; fcu = fcu->next) {
-               /* Check if this F-Curve doesn't belong to a muted group. */
-               if ((fcu->grp != NULL) && (fcu->grp->flag & AGRP_MUTED)) {
-                       continue;
-               }
-               /* Check if this curve should be skipped. */
-               if ((fcu->flag & (FCURVE_MUTED | FCURVE_DISABLED))) {
-                       continue;
-               }
-               PathResolvedRNA anim_rna;
-               if (animsys_store_rna_setting(ptr, fcu->rna_path, fcu->array_index, &anim_rna)) {
-                       const float curval = calculate_fcurve(&anim_rna, fcu, ctime);
-                       animsys_write_rna_setting(&anim_rna, curval);
-                       if (is_active_depsgraph) {
-                               animsys_write_orig_anim_rna(ptr, fcu->rna_path, fcu->array_index, curval);
-                       }
-               }
-       }
+static void animsys_evaluate_fcurves(Depsgraph *depsgraph,
+                                     PointerRNA *ptr,
+                                     ListBase *list,
+                                     float ctime)
+{
+  const bool is_active_depsgraph = DEG_is_active(depsgraph);
+  /* Calculate then execute each curve. */
+  for (FCurve *fcu = list->first; fcu; fcu = fcu->next) {
+    /* Check if this F-Curve doesn't belong to a muted group. */
+    if ((fcu->grp != NULL) && (fcu->grp->flag & AGRP_MUTED)) {
+      continue;
+    }
+    /* Check if this curve should be skipped. */
+    if ((fcu->flag & (FCURVE_MUTED | FCURVE_DISABLED))) {
+      continue;
+    }
+    PathResolvedRNA anim_rna;
+    if (animsys_store_rna_setting(ptr, fcu->rna_path, fcu->array_index, &anim_rna)) {
+      const float curval = calculate_fcurve(&anim_rna, fcu, ctime);
+      animsys_write_rna_setting(&anim_rna, curval);
+      if (is_active_depsgraph) {
+        animsys_write_orig_anim_rna(ptr, fcu->rna_path, fcu->array_index, curval);
+      }
+    }
+  }
 }
 
 /* ***************************************** */
@@ -1748,36 +1883,37 @@ static void animsys_evaluate_fcurves(
 /* Evaluate Drivers */
 static void animsys_evaluate_drivers(PointerRNA *ptr, AnimData *adt, float ctime)
 {
-       FCurve *fcu;
-
-       /* drivers are stored as F-Curves, but we cannot use the standard code, as we need to check if
-        * the depsgraph requested that this driver be evaluated...
-        */
-       for (fcu = adt->drivers.first; fcu; fcu = fcu->next) {
-               ChannelDriver *driver = fcu->driver;
-               bool ok = false;
-
-               /* check if this driver's curve should be skipped */
-               if ((fcu->flag & (FCURVE_MUTED | FCURVE_DISABLED)) == 0) {
-                       /* check if driver itself is tagged for recalculation */
-                       /* XXX driver recalc flag is not set yet by depsgraph! */
-                       if ((driver) && !(driver->flag & DRIVER_FLAG_INVALID)) {
-                               /* evaluate this using values set already in other places
-                                * NOTE: for 'layering' option later on, we should check if we should remove old value before adding
-                                *       new to only be done when drivers only changed */
-
-                               PathResolvedRNA anim_rna;
-                               if (animsys_store_rna_setting(ptr, fcu->rna_path, fcu->array_index, &anim_rna)) {
-                                       const float curval = calculate_fcurve(&anim_rna, fcu, ctime);
-                                       ok = animsys_write_rna_setting(&anim_rna, curval);
-                               }
-
-                               /* set error-flag if evaluation failed */
-                               if (ok == 0)
-                                       driver->flag |= DRIVER_FLAG_INVALID;
-                       }
-               }
-       }
+  FCurve *fcu;
+
+  /* drivers are stored as F-Curves, but we cannot use the standard code, as we need to check if
+   * the depsgraph requested that this driver be evaluated...
+   */
+  for (fcu = adt->drivers.first; fcu; fcu = fcu->next) {
+    ChannelDriver *driver = fcu->driver;
+    bool ok = false;
+
+    /* check if this driver's curve should be skipped */
+    if ((fcu->flag & (FCURVE_MUTED | FCURVE_DISABLED)) == 0) {
+      /* check if driver itself is tagged for recalculation */
+      /* XXX driver recalc flag is not set yet by depsgraph! */
+      if ((driver) && !(driver->flag & DRIVER_FLAG_INVALID)) {
+        /* evaluate this using values set already in other places
+         * NOTE: for 'layering' option later on, we should check if we should remove old value before adding
+         *       new to only be done when drivers only changed */
+
+        PathResolvedRNA anim_rna;
+        if (animsys_store_rna_setting(ptr, fcu->rna_path, fcu->array_index, &anim_rna)) {
+          const float curval = calculate_fcurve(&anim_rna, fcu, ctime);
+          ok = animsys_write_rna_setting(&anim_rna, curval);
+        }
+
+        /* set error-flag if evaluation failed */
+        if (ok == 0) {
+          driver->flag |= DRIVER_FLAG_INVALID;
+        }
+      }
+    }
+  }
 }
 
 /* ***************************************** */
@@ -1789,29 +1925,35 @@ static void animsys_evaluate_drivers(PointerRNA *ptr, AnimData *adt, float ctime
  */
 static void action_idcode_patch_check(ID *id, bAction *act)
 {
-       int idcode = 0;
-
-       /* just in case */
-       if (ELEM(NULL, id, act))
-               return;
-       else
-               idcode = GS(id->name);
-
-       /* the actual checks... hopefully not too much of a performance hit in the long run... */
-       if (act->idroot == 0) {
-               /* use the current root if not set already (i.e. newly created actions and actions from 2.50-2.57 builds)
-                * - this has problems if there are 2 users, and the first one encountered is the invalid one
-                *   in which case, the user will need to manually fix this (?)
-                */
-               act->idroot = idcode;
-       }
-       else if (act->idroot != idcode) {
-               /* only report this error if debug mode is enabled (to save performance everywhere else) */
-               if (G.debug & G_DEBUG) {
-                       printf("AnimSys Safety Check Failed: Action '%s' is not meant to be used from ID-Blocks of type %d such as '%s'\n",
-                              act->id.name + 2, idcode, id->name);
-               }
-       }
+  int idcode = 0;
+
+  /* just in case */
+  if (ELEM(NULL, id, act)) {
+    return;
+  }
+  else {
+    idcode = GS(id->name);
+  }
+
+  /* the actual checks... hopefully not too much of a performance hit in the long run... */
+  if (act->idroot == 0) {
+    /* use the current root if not set already (i.e. newly created actions and actions from 2.50-2.57 builds)
+     * - this has problems if there are 2 users, and the first one encountered is the invalid one
+     *   in which case, the user will need to manually fix this (?)
+     */
+    act->idroot = idcode;
+  }
+  else if (act->idroot != idcode) {
+    /* only report this error if debug mode is enabled (to save performance everywhere else) */
+    if (G.debug & G_DEBUG) {
+      printf(
+          "AnimSys Safety Check Failed: Action '%s' is not meant to be used from ID-Blocks of "
+          "type %d such as '%s'\n",
+          act->id.name + 2,
+          idcode,
+          id->name);
+    }
+  }
 }
 
 /* ----------------------------------------- */
@@ -1819,46 +1961,53 @@ static void action_idcode_patch_check(ID *id, bAction *act)
 /* Evaluate Action Group */
 void animsys_evaluate_action_group(PointerRNA *ptr, bAction *act, bActionGroup *agrp, float ctime)
 {
-       FCurve *fcu;
+  FCurve *fcu;
 
-       /* check if mapper is appropriate for use here (we set to NULL if it's inappropriate) */
-       if (ELEM(NULL, act, agrp)) return;
+  /* check if mapper is appropriate for use here (we set to NULL if it's inappropriate) */
+  if (ELEM(NULL, act, agrp)) {
+    return;
+  }
 
-       action_idcode_patch_check(ptr->id.data, act);
+  action_idcode_patch_check(ptr->id.data, act);
 
-       /* if group is muted, don't evaluated any of the F-Curve */
-       if (agrp->flag & AGRP_MUTED)
-               return;
+  /* if group is muted, don't evaluated any of the F-Curve */
+  if (agrp->flag & AGRP_MUTED) {
+    return;
+  }
 
-       /* calculate then execute each curve */
-       for (fcu = agrp->channels.first; (fcu) && (fcu->grp == agrp); fcu = fcu->next) {
-               /* check if this curve should be skipped */
-               if ((fcu->flag & (FCURVE_MUTED | FCURVE_DISABLED)) == 0) {
-                       PathResolvedRNA anim_rna;
-                       if (animsys_store_rna_setting(ptr, fcu->rna_path, fcu->array_index, &anim_rna)) {
-                               const float curval = calculate_fcurve(&anim_rna, fcu, ctime);
-                               animsys_write_rna_setting(&anim_rna, curval);
-                       }
-               }
-       }
+  /* calculate then execute each curve */
+  for (fcu = agrp->channels.first; (fcu) && (fcu->grp == agrp); fcu = fcu->next) {
+    /* check if this curve should be skipped */
+    if ((fcu->flag & (FCURVE_MUTED | FCURVE_DISABLED)) == 0) {
+      PathResolvedRNA anim_rna;
+      if (animsys_store_rna_setting(ptr, fcu->rna_path, fcu->array_index, &anim_rna)) {
+        const float curval = calculate_fcurve(&anim_rna, fcu, ctime);
+        animsys_write_rna_setting(&anim_rna, curval);
+      }
+    }
+  }
 }
 
 /* Evaluate Action (F-Curve Bag) */
-static void animsys_evaluate_action_ex(
-        Depsgraph *depsgraph, PointerRNA *ptr, bAction *act, float ctime)
+static void animsys_evaluate_action_ex(Depsgraph *depsgraph,
+                                       PointerRNA *ptr,
+                                       bAction *act,
+                                       float ctime)
 {
-       /* check if mapper is appropriate for use here (we set to NULL if it's inappropriate) */
-       if (act == NULL) return;
+  /* check if mapper is appropriate for use here (we set to NULL if it's inappropriate) */
+  if (act == NULL) {
+    return;
+  }
 
-       action_idcode_patch_check(ptr->id.data, act);
+  action_idcode_patch_check(ptr->id.data, act);
 
-       /* calculate then execute each curve */
-       animsys_evaluate_fcurves(depsgraph, ptr, &act->curves, ctime);
+  /* calculate then execute each curve */
+  animsys_evaluate_fcurves(depsgraph, ptr, &act->curves, ctime);
 }
 
 void animsys_evaluate_action(Depsgraph *depsgraph, PointerRNA *ptr, bAction *act, float ctime)
 {
-       animsys_evaluate_action_ex(depsgraph, ptr, act, ctime);
+  animsys_evaluate_action_ex(depsgraph, ptr, act, ctime);
 }
 
 /* ***************************************** */
@@ -1867,178 +2016,191 @@ void animsys_evaluate_action(Depsgraph *depsgraph, PointerRNA *ptr, bAction *act
 /* calculate influence of strip based for given frame based on blendin/out values */
 static float nlastrip_get_influence(NlaStrip *strip, float cframe)
 {
-       /* sanity checks - normalize the blendin/out values? */
-       strip->blendin = fabsf(strip->blendin);
-       strip->blendout = fabsf(strip->blendout);
-
-       /* result depends on where frame is in respect to blendin/out values */
-       if (IS_EQF(strip->blendin, 0.0f) == false && (cframe <= (strip->start + strip->blendin))) {
-               /* there is some blend-in */
-               return fabsf(cframe - strip->start) / (strip->blendin);
-       }
-       else if (IS_EQF(strip->blendout, 0.0f) == false && (cframe >= (strip->end - strip->blendout))) {
-               /* there is some blend-out */
-               return fabsf(strip->end - cframe) / (strip->blendout);
-       }
-       else {
-               /* in the middle of the strip, we should be full strength */
-               return 1.0f;
-       }
+  /* sanity checks - normalize the blendin/out values? */
+  strip->blendin = fabsf(strip->blendin);
+  strip->blendout = fabsf(strip->blendout);
+
+  /* result depends on where frame is in respect to blendin/out values */
+  if (IS_EQF(strip->blendin, 0.0f) == false && (cframe <= (strip->start + strip->blendin))) {
+    /* there is some blend-in */
+    return fabsf(cframe - strip->start) / (strip->blendin);
+  }
+  else if (IS_EQF(strip->blendout, 0.0f) == false && (cframe >= (strip->end - strip->blendout))) {
+    /* there is some blend-out */
+    return fabsf(strip->end - cframe) / (strip->blendout);
+  }
+  else {
+    /* in the middle of the strip, we should be full strength */
+    return 1.0f;
+  }
 }
 
 /* evaluate the evaluation time and influence for the strip, storing the results in the strip */
 static void nlastrip_evaluate_controls(Depsgraph *depsgraph, NlaStrip *strip, float ctime)
 {
-       /* now strip's evaluate F-Curves for these settings (if applicable) */
-       if (strip->fcurves.first) {
-               PointerRNA strip_ptr;
-
-               /* create RNA-pointer needed to set values */
-               RNA_pointer_create(NULL, &RNA_NlaStrip, strip, &strip_ptr);
-
-               /* execute these settings as per normal */
-               animsys_evaluate_fcurves(depsgraph, &strip_ptr, &strip->fcurves, ctime);
-       }
-
-       /* analytically generate values for influence and time (if applicable)
-        * - we do this after the F-Curves have been evaluated to override the effects of those
-        *   in case the override has been turned off.
-        */
-       if ((strip->flag & NLASTRIP_FLAG_USR_INFLUENCE) == 0)
-               strip->influence = nlastrip_get_influence(strip, ctime);
-
-       /* Bypass evaluation time computation if time mapping is disabled. */
-       if ((strip->flag & NLASTRIP_FLAG_NO_TIME_MAP) != 0) {
-               strip->strip_time = ctime;
-               return;
-       }
-
-       if ((strip->flag & NLASTRIP_FLAG_USR_TIME) == 0)
-               strip->strip_time = nlastrip_get_frame(strip, ctime, NLATIME_CONVERT_EVAL);
-
-       /* if user can control the evaluation time (using F-Curves), consider the option which allows this time to be clamped
-        * to lie within extents of the action-clip, so that a steady changing rate of progress through several cycles of the clip
-        * can be achieved easily
-        */
-       /* NOTE: if we add any more of these special cases, we better group them up nicely... */
-       if ((strip->flag & NLASTRIP_FLAG_USR_TIME) && (strip->flag & NLASTRIP_FLAG_USR_TIME_CYCLIC))
-               strip->strip_time = fmod(strip->strip_time - strip->actstart, strip->actend - strip->actstart);
+  /* now strip's evaluate F-Curves for these settings (if applicable) */
+  if (strip->fcurves.first) {
+    PointerRNA strip_ptr;
+
+    /* create RNA-pointer needed to set values */
+    RNA_pointer_create(NULL, &RNA_NlaStrip, strip, &strip_ptr);
+
+    /* execute these settings as per normal */
+    animsys_evaluate_fcurves(depsgraph, &strip_ptr, &strip->fcurves, ctime);
+  }
+
+  /* analytically generate values for influence and time (if applicable)
+   * - we do this after the F-Curves have been evaluated to override the effects of those
+   *   in case the override has been turned off.
+   */
+  if ((strip->flag & NLASTRIP_FLAG_USR_INFLUENCE) == 0) {
+    strip->influence = nlastrip_get_influence(strip, ctime);
+  }
+
+  /* Bypass evaluation time computation if time mapping is disabled. */
+  if ((strip->flag & NLASTRIP_FLAG_NO_TIME_MAP) != 0) {
+    strip->strip_time = ctime;
+    return;
+  }
+
+  if ((strip->flag & NLASTRIP_FLAG_USR_TIME) == 0) {
+    strip->strip_time = nlastrip_get_frame(strip, ctime, NLATIME_CONVERT_EVAL);
+  }
+
+  /* if user can control the evaluation time (using F-Curves), consider the option which allows this time to be clamped
+   * to lie within extents of the action-clip, so that a steady changing rate of progress through several cycles of the clip
+   * can be achieved easily
+   */
+  /* NOTE: if we add any more of these special cases, we better group them up nicely... */
+  if ((strip->flag & NLASTRIP_FLAG_USR_TIME) && (strip->flag & NLASTRIP_FLAG_USR_TIME_CYCLIC)) {
+    strip->strip_time = fmod(strip->strip_time - strip->actstart, strip->actend - strip->actstart);
+  }
 }
 
 /* gets the strip active at the current time for a list of strips for evaluation purposes */
-NlaEvalStrip *nlastrips_ctime_get_strip(Depsgraph *depsgraph, ListBase *list, ListBase *strips, short index, float ctime)
-{
-       NlaStrip *strip, *estrip = NULL;
-       NlaEvalStrip *nes;
-       short side = 0;
-
-       /* loop over strips, checking if they fall within the range */
-       for (strip = strips->first; strip; strip = strip->next) {
-               /* check if current time occurs within this strip  */
-               if (IN_RANGE_INCL(ctime, strip->start, strip->end) || (strip->flag & NLASTRIP_FLAG_NO_TIME_MAP)) {
-                       /* this strip is active, so try to use it */
-                       estrip = strip;
-                       side = NES_TIME_WITHIN;
-                       break;
-               }
-
-               /* if time occurred before current strip... */
-               if (ctime < strip->start) {
-                       if (strip == strips->first) {
-                               /* before first strip - only try to use it if it extends backwards in time too */
-                               if (strip->extendmode == NLASTRIP_EXTEND_HOLD)
-                                       estrip = strip;
-
-                               /* side is 'before' regardless of whether there's a useful strip */
-                               side = NES_TIME_BEFORE;
-                       }
-                       else {
-                               /* before next strip - previous strip has ended, but next hasn't begun,
-                                * so blending mode depends on whether strip is being held or not...
-                                * - only occurs when no transition strip added, otherwise the transition would have
-                                *   been picked up above...
-                                */
-                               strip = strip->prev;
-
-                               if (strip->extendmode != NLASTRIP_EXTEND_NOTHING)
-                                       estrip = strip;
-                               side = NES_TIME_AFTER;
-                       }
-                       break;
-               }
-
-               /* if time occurred after current strip... */
-               if (ctime > strip->end) {
-                       /* only if this is the last strip should we do anything, and only if that is being held */
-                       if (strip == strips->last) {
-                               if (strip->extendmode != NLASTRIP_EXTEND_NOTHING)
-                                       estrip = strip;
-
-                               side = NES_TIME_AFTER;
-                               break;
-                       }
-
-                       /* otherwise, skip... as the 'before' case will catch it more elegantly! */
-               }
-       }
-
-       /* check if a valid strip was found
-        * - must not be muted (i.e. will have contribution
-        */
-       if ((estrip == NULL) || (estrip->flag & NLASTRIP_FLAG_MUTED))
-               return NULL;
-
-       /* if ctime was not within the boundaries of the strip, clamp! */
-       switch (side) {
-               case NES_TIME_BEFORE: /* extend first frame only */
-                       ctime = estrip->start;
-                       break;
-               case NES_TIME_AFTER: /* extend last frame only */
-                       ctime = estrip->end;
-                       break;
-       }
-
-       /* evaluate strip's evaluation controls
-        * - skip if no influence (i.e. same effect as muting the strip)
-        * - negative influence is not supported yet... how would that be defined?
-        */
-       /* TODO: this sounds a bit hacky having a few isolated F-Curves stuck on some data it operates on... */
-       nlastrip_evaluate_controls(depsgraph, estrip, ctime);
-       if (estrip->influence <= 0.0f)
-               return NULL;
-
-       /* check if strip has valid data to evaluate,
-        * and/or perform any additional type-specific actions
-        */
-       switch (estrip->type) {
-               case NLASTRIP_TYPE_CLIP:
-                       /* clip must have some action to evaluate */
-                       if (estrip->act == NULL)
-                               return NULL;
-                       break;
-               case NLASTRIP_TYPE_TRANSITION:
-                       /* there must be strips to transition from and to (i.e. prev and next required) */
-                       if (ELEM(NULL, estrip->prev, estrip->next))
-                               return NULL;
-
-                       /* evaluate controls for the relevant extents of the bordering strips... */
-                       nlastrip_evaluate_controls(depsgraph, estrip->prev, estrip->start);
-                       nlastrip_evaluate_controls(depsgraph, estrip->next, estrip->end);
-                       break;
-       }
-
-       /* add to list of strips we need to evaluate */
-       nes = MEM_callocN(sizeof(NlaEvalStrip), "NlaEvalStrip");
-
-       nes->strip = estrip;
-       nes->strip_mode = side;
-       nes->track_index = index;
-       nes->strip_time = estrip->strip_time;
-
-       if (list)
-               BLI_addtail(list, nes);
-
-       return nes;
+NlaEvalStrip *nlastrips_ctime_get_strip(
+    Depsgraph *depsgraph, ListBase *list, ListBase *strips, short index, float ctime)
+{
+  NlaStrip *strip, *estrip = NULL;
+  NlaEvalStrip *nes;
+  short side = 0;
+
+  /* loop over strips, checking if they fall within the range */
+  for (strip = strips->first; strip; strip = strip->next) {
+    /* check if current time occurs within this strip  */
+    if (IN_RANGE_INCL(ctime, strip->start, strip->end) ||
+        (strip->flag & NLASTRIP_FLAG_NO_TIME_MAP)) {
+      /* this strip is active, so try to use it */
+      estrip = strip;
+      side = NES_TIME_WITHIN;
+      break;
+    }
+
+    /* if time occurred before current strip... */
+    if (ctime < strip->start) {
+      if (strip == strips->first) {
+        /* before first strip - only try to use it if it extends backwards in time too */
+        if (strip->extendmode == NLASTRIP_EXTEND_HOLD) {
+          estrip = strip;
+        }
+
+        /* side is 'before' regardless of whether there's a useful strip */
+        side = NES_TIME_BEFORE;
+      }
+      else {
+        /* before next strip - previous strip has ended, but next hasn't begun,
+         * so blending mode depends on whether strip is being held or not...
+         * - only occurs when no transition strip added, otherwise the transition would have
+         *   been picked up above...
+         */
+        strip = strip->prev;
+
+        if (strip->extendmode != NLASTRIP_EXTEND_NOTHING) {
+          estrip = strip;
+        }
+        side = NES_TIME_AFTER;
+      }
+      break;
+    }
+
+    /* if time occurred after current strip... */
+    if (ctime > strip->end) {
+      /* only if this is the last strip should we do anything, and only if that is being held */
+      if (strip == strips->last) {
+        if (strip->extendmode != NLASTRIP_EXTEND_NOTHING) {
+          estrip = strip;
+        }
+
+        side = NES_TIME_AFTER;
+        break;
+      }
+
+      /* otherwise, skip... as the 'before' case will catch it more elegantly! */
+    }
+  }
+
+  /* check if a valid strip was found
+   * - must not be muted (i.e. will have contribution
+   */
+  if ((estrip == NULL) || (estrip->flag & NLASTRIP_FLAG_MUTED)) {
+    return NULL;
+  }
+
+  /* if ctime was not within the boundaries of the strip, clamp! */
+  switch (side) {
+    case NES_TIME_BEFORE: /* extend first frame only */
+      ctime = estrip->start;
+      break;
+    case NES_TIME_AFTER: /* extend last frame only */
+      ctime = estrip->end;
+      break;
+  }
+
+  /* evaluate strip's evaluation controls
+   * - skip if no influence (i.e. same effect as muting the strip)
+   * - negative influence is not supported yet... how would that be defined?
+   */
+  /* TODO: this sounds a bit hacky having a few isolated F-Curves stuck on some data it operates on... */
+  nlastrip_evaluate_controls(depsgraph, estrip, ctime);
+  if (estrip->influence <= 0.0f) {
+    return NULL;
+  }
+
+  /* check if strip has valid data to evaluate,
+   * and/or perform any additional type-specific actions
+   */
+  switch (estrip->type) {
+    case NLASTRIP_TYPE_CLIP:
+      /* clip must have some action to evaluate */
+      if (estrip->act == NULL) {
+        return NULL;
+      }
+      break;
+    case NLASTRIP_TYPE_TRANSITION:
+      /* there must be strips to transition from and to (i.e. prev and next required) */
+      if (ELEM(NULL, estrip->prev, estrip->next)) {
+        return NULL;
+      }
+
+      /* evaluate controls for the relevant extents of the bordering strips... */
+      nlastrip_evaluate_controls(depsgraph, estrip->prev, estrip->start);
+      nlastrip_evaluate_controls(depsgraph, estrip->next, estrip->end);
+      break;
+  }
+
+  /* add to list of strips we need to evaluate */
+  nes = MEM_callocN(sizeof(NlaEvalStrip), "NlaEvalStrip");
+
+  nes->strip = estrip;
+  nes->strip_mode = side;
+  nes->track_index = index;
+  nes->strip_time = estrip->strip_time;
+
+  if (list) {
+    BLI_addtail(list, nes);
+  }
+
+  return nes;
 }
 
 /* ---------------------- */
@@ -2046,20 +2208,20 @@ NlaEvalStrip *nlastrips_ctime_get_strip(Depsgraph *depsgraph, ListBase *list, Li
 /* Initialize a valid mask, allocating memory if necessary. */
 static void nlavalidmask_init(NlaValidMask *mask, int bits)
 {
-       if (BLI_BITMAP_SIZE(bits) > sizeof(mask->buffer)) {
-               mask->ptr = BLI_BITMAP_NEW(bits, "NlaValidMask");
-       }
-       else {
-               mask->ptr = mask->buffer;
-       }
+  if (BLI_BITMAP_SIZE(bits) > sizeof(mask->buffer)) {
+    mask->ptr = BLI_BITMAP_NEW(bits, "NlaValidMask");
+  }
+  else {
+    mask->ptr = mask->buffer;
+  }
 }
 
 /* Free allocated memory for the mask. */
 static void nlavalidmask_free(NlaValidMask *mask)
 {
-       if (mask->ptr != mask->buffer) {
-               MEM_freeN(mask->ptr);
-       }
+  if (mask->ptr != mask->buffer) {
+    MEM_freeN(mask->ptr);
+  }
 }
 
 /* ---------------------- */
@@ -2067,18 +2229,17 @@ static void nlavalidmask_free(NlaValidMask *mask)
 /* Hashing functions for NlaEvalChannelKey. */
 static uint nlaevalchan_keyhash(const void *ptr)
 {
-       const NlaEvalChannelKey *key = ptr;
-       uint hash = BLI_ghashutil_ptrhash(key->ptr.data);
-       return hash ^ BLI_ghashutil_ptrhash(key->prop);
+  const NlaEvalChannelKey *key = ptr;
+  uint hash = BLI_ghashutil_ptrhash(key->ptr.data);
+  return hash ^ BLI_ghashutil_ptrhash(key->prop);
 }
 
 static bool nlaevalchan_keycmp(const void *a, const void *b)
 {
-       const NlaEvalChannelKey *A = a;
-       const NlaEvalChannelKey *B = b;
+  const NlaEvalChannelKey *A = a;
+  const NlaEvalChannelKey *B = b;
 
-       return ((A->ptr.data != B->ptr.data) ||
-               (A->prop != B->prop));
+  return ((A->ptr.data != B->ptr.data) || (A->prop != B->prop));
 }
 
 /* ---------------------- */
@@ -2086,119 +2247,127 @@ static bool nlaevalchan_keycmp(const void *a, const void *b)
 /* Allocate a new blending value snapshot for the channel. */
 static NlaEvalChannelSnapshot *nlaevalchan_snapshot_new(NlaEvalChannel *nec)
 {
-       int length = nec->base_snapshot.length;
+  int length = nec->base_snapshot.length;
 
-       size_t byte_size = sizeof(NlaEvalChannelSnapshot) + sizeof(float) * length;
-       NlaEvalChannelSnapshot *nec_snapshot = MEM_callocN(byte_size, "NlaEvalChannelSnapshot");
+  size_t byte_size = sizeof(NlaEvalChannelSnapshot) + sizeof(float) * length;
+  NlaEvalChannelSnapshot *nec_snapshot = MEM_callocN(byte_size, "NlaEvalChannelSnapshot");
 
-       nec_snapshot->channel = nec;
-       nec_snapshot->length = length;
+  nec_snapshot->channel = nec;
+  nec_snapshot->length = length;
 
-       return nec_snapshot;
+  return nec_snapshot;
 }
 
 /* Free a channel's blending value snapshot. */
 static void nlaevalchan_snapshot_free(NlaEvalChannelSnapshot *nec_snapshot)
 {
-       BLI_assert(!nec_snapshot->is_base);
+  BLI_assert(!nec_snapshot->is_base);
 
-       MEM_freeN(nec_snapshot);
+  MEM_freeN(nec_snapshot);
 }
 
 /* Copy all data in the snapshot. */
-static void nlaevalchan_snapshot_copy(NlaEvalChannelSnapshot *dst, const NlaEvalChannelSnapshot *src)
+static void nlaevalchan_snapshot_copy(NlaEvalChannelSnapshot *dst,
+                                      const NlaEvalChannelSnapshot *src)
 {
-       BLI_assert(dst->channel == src->channel);
+  BLI_assert(dst->channel == src->channel);
 
-       memcpy(dst->values, src->values, sizeof(float) * dst->length);
+  memcpy(dst->values, src->values, sizeof(float) * dst->length);
 }
 
 /* ---------------------- */
 
 /* Initialize a blending state snapshot structure. */
-static void nlaeval_snapshot_init(NlaEvalSnapshot *snapshot, NlaEvalData *nlaeval, NlaEvalSnapshot *base)
+static void nlaeval_snapshot_init(NlaEvalSnapshot *snapshot,
+                                  NlaEvalData *nlaeval,
+                                  NlaEvalSnapshot *base)
 {
-       snapshot->base = base;
-       snapshot->size = MAX2(16, nlaeval->num_channels);
-       snapshot->channels = MEM_callocN(sizeof(*snapshot->channels) * snapshot->size, "NlaEvalSnapshot::channels");
+  snapshot->base = base;
+  snapshot->size = MAX2(16, nlaeval->num_channels);
+  snapshot->channels = MEM_callocN(sizeof(*snapshot->channels) * snapshot->size,
+                                   "NlaEvalSnapshot::channels");
 }
 
 /* Retrieve the individual channel snapshot. */
 static NlaEvalChannelSnapshot *nlaeval_snapshot_get(NlaEvalSnapshot *snapshot, int index)
 {
-       return (index < snapshot->size) ? snapshot->channels[index] : NULL;
+  return (index < snapshot->size) ? snapshot->channels[index] : NULL;
 }
 
 /* Ensure at least this number of slots exists. */
 static void nlaeval_snapshot_ensure_size(NlaEvalSnapshot *snapshot, int size)
 {
-       if (size > snapshot->size) {
-               snapshot->size *= 2;
-               CLAMP_MIN(snapshot->size, size);
-               CLAMP_MIN(snapshot->size, 16);
+  if (size > snapshot->size) {
+    snapshot->size *= 2;
+    CLAMP_MIN(snapshot->size, size);
+    CLAMP_MIN(snapshot->size, 16);
 
-               size_t byte_size = sizeof(*snapshot->channels) * snapshot->size;
-               snapshot->channels = MEM_recallocN_id(snapshot->channels, byte_size, "NlaEvalSnapshot::channels");
-       }
+    size_t byte_size = sizeof(*snapshot->channels) * snapshot->size;
+    snapshot->channels = MEM_recallocN_id(
+        snapshot->channels, byte_size, "NlaEvalSnapshot::channels");
+  }
 }
 
 /* Retrieve the address of a slot in the blending state snapshot for this channel (may realloc). */
-static NlaEvalChannelSnapshot **nlaeval_snapshot_ensure_slot(NlaEvalSnapshot *snapshot, NlaEvalChannel *nec)
+static NlaEvalChannelSnapshot **nlaeval_snapshot_ensure_slot(NlaEvalSnapshot *snapshot,
+                                                             NlaEvalChannel *nec)
 {
-       nlaeval_snapshot_ensure_size(snapshot, nec->owner->num_channels);
-       return &snapshot->channels[nec->index];
+  nlaeval_snapshot_ensure_size(snapshot, nec->owner->num_channels);
+  return &snapshot->channels[nec->index];
 }
 
 /* Retrieve the blending snapshot for the specified channel, with fallback to base. */
-static NlaEvalChannelSnapshot *nlaeval_snapshot_find_channel(NlaEvalSnapshot *snapshot, NlaEvalChannel *nec)
+static NlaEvalChannelSnapshot *nlaeval_snapshot_find_channel(NlaEvalSnapshot *snapshot,
+                                                             NlaEvalChannel *nec)
 {
-       while (snapshot != NULL) {
-               NlaEvalChannelSnapshot *nec_snapshot = nlaeval_snapshot_get(snapshot, nec->index);
-               if (nec_snapshot != NULL) {
-                       return nec_snapshot;
-               }
-               snapshot = snapshot->base;
-       }
+  while (snapshot != NULL) {
+    NlaEvalChannelSnapshot *nec_snapshot = nlaeval_snapshot_get(snapshot, nec->index);
+    if (nec_snapshot != NULL) {
+      return nec_snapshot;
+    }
+    snapshot = snapshot->base;
+  }
 
-       return &nec->base_snapshot;
+  return &nec->base_snapshot;
 }
 
 /* Retrieve or create the channel value snapshot, copying from the other snapshot (or default values) */
-static NlaEvalChannelSnapshot *nlaeval_snapshot_ensure_channel(NlaEvalSnapshot *snapshot, NlaEvalChannel *nec)
+static NlaEvalChannelSnapshot *nlaeval_snapshot_ensure_channel(NlaEvalSnapshot *snapshot,
+                                                               NlaEvalChannel *nec)
 {
-       NlaEvalChannelSnapshot **slot = nlaeval_snapshot_ensure_slot(snapshot, nec);
+  NlaEvalChannelSnapshot **slot = nlaeval_snapshot_ensure_slot(snapshot, nec);
 
-       if (*slot == NULL) {
-               NlaEvalChannelSnapshot *base_snapshot, *nec_snapshot;
+  if (*slot == NULL) {
+    NlaEvalChannelSnapshot *base_snapshot, *nec_snapshot;
 
-               nec_snapshot = nlaevalchan_snapshot_new(nec);
-               base_snapshot = nlaeval_snapshot_find_channel(snapshot->base, nec);
+    nec_snapshot = nlaevalchan_snapshot_new(nec);
+    base_snapshot = nlaeval_snapshot_find_channel(snapshot->base, nec);
 
-               nlaevalchan_snapshot_copy(nec_snapshot, base_snapshot);
+    nlaevalchan_snapshot_copy(nec_snapshot, base_snapshot);
 
-               *slot = nec_snapshot;
-       }
+    *slot = nec_snapshot;
+  }
 
-       return *slot;
+  return *slot;
 }
 
 /* Free all memory owned by this blending snapshot structure. */
 static void nlaeval_snapshot_free_data(NlaEvalSnapshot *snapshot)
 {
-       if (snapshot->channels != NULL) {
-               for (int i = 0; i < snapshot->size; i++) {
-                       NlaEvalChannelSnapshot *nec_snapshot = snapshot->channels[i];
-                       if (nec_snapshot != NULL) {
-                               nlaevalchan_snapshot_free(nec_snapshot);
-                       }
-               }
+  if (snapshot->channels != NULL) {
+    for (int i = 0; i < snapshot->size; i++) {
+      NlaEvalChannelSnapshot *nec_snapshot = snapshot->channels[i];
+      if (nec_snapshot != NULL) {
+        nlaevalchan_snapshot_free(nec_snapshot);
+      }
+    }
 
-               MEM_freeN(snapshot->channels);
-       }
+    MEM_freeN(snapshot->channels);
+  }
 
-       snapshot->base = NULL;
-       snapshot->size = 0;
-       snapshot->channels = NULL;
+  snapshot->base = NULL;
+  snapshot->size = 0;
+  snapshot->channels = NULL;
 }
 
 /* ---------------------- */
@@ -2206,240 +2375,253 @@ static void nlaeval_snapshot_free_data(NlaEvalSnapshot *snapshot)
 /* Free memory owned by this evaluation channel. */
 static void nlaevalchan_free_data(NlaEvalChannel *nec)
 {
-       nlavalidmask_free(&nec->valid);
+  nlavalidmask_free(&nec->valid);
 
-       if (nec->blend_snapshot != NULL) {
-               nlaevalchan_snapshot_free(nec->blend_snapshot);
-       }
+  if (nec->blend_snapshot != NULL) {
+    nlaevalchan_snapshot_free(nec->blend_snapshot);
+  }
 }
 
 /* Initialize a full NLA evaluation state structure. */
 static void nlaeval_init(NlaEvalData *nlaeval)
 {
-       memset(nlaeval, 0, sizeof(*nlaeval));
+  memset(nlaeval, 0, sizeof(*nlaeval));
 
-       nlaeval->path_hash = BLI_ghash_str_new("NlaEvalData::path_hash");
-       nlaeval->key_hash = BLI_ghash_new(nlaevalchan_keyhash, nlaevalchan_keycmp, "NlaEvalData::key_hash");
+  nlaeval->path_hash = BLI_ghash_str_new("NlaEvalData::path_hash");
+  nlaeval->key_hash = BLI_ghash_new(
+      nlaevalchan_keyhash, nlaevalchan_keycmp, "NlaEvalData::key_hash");
 }
 
 static void nlaeval_free(NlaEvalData *nlaeval)
 {
-       /* Delete base snapshot - its channels are part of NlaEvalChannel and shouldn't be freed. */
-       MEM_SAFE_FREE(nlaeval->base_snapshot.channels);
+  /* Delete base snapshot - its channels are part of NlaEvalChannel and shouldn't be freed. */
+  MEM_SAFE_FREE(nlaeval->base_snapshot.channels);
 
-       /* Delete result snapshot. */
-       nlaeval_snapshot_free_data(&nlaeval->eval_snapshot);
+  /* Delete result snapshot. */
+  nlaeval_snapshot_free_data(&nlaeval->eval_snapshot);
 
-       /* Delete channels. */
-       for (NlaEvalChannel *nec = nlaeval->channels.first; nec; nec = nec->next) {
-               nlaevalchan_free_data(nec);
-       }
+  /* Delete channels. */
+  for (NlaEvalChannel *nec = nlaeval->channels.first; nec; nec = nec->next) {
+    nlaevalchan_free_data(nec);
+  }
 
-       BLI_freelistN(&nlaeval->channels);
-       BLI_ghash_free(nlaeval->path_hash, NULL, NULL);
-       BLI_ghash_free(nlaeval->key_hash, NULL, NULL);
+  BLI_freelistN(&nlaeval->channels);
+  BLI_ghash_free(nlaeval->path_hash, NULL, NULL);
+  BLI_ghash_free(nlaeval->key_hash, NULL, NULL);
 }
 
 /* ---------------------- */
 
 static int nlaevalchan_validate_index(NlaEvalChannel *nec, int index)
 {
-       if (nec->is_array) {
-               if (index >= 0 && index < nec->base_snapshot.length) {
-                       return index;
-               }
+  if (nec->is_array) {
+    if (index >= 0 && index < nec->base_snapshot.length) {
+      return index;
+    }
 
-               return -1;
-       }
-       else {
-               return 0;
-       }
+    return -1;
+  }
+  else {
+    return 0;
+  }
 }
 
 /* Initialise default values for NlaEvalChannel from the property data. */
 static void nlaevalchan_get_default_values(NlaEvalChannel *nec, float *r_values)
 {
-       PointerRNA *ptr = &nec->key.ptr;
-       PropertyRNA *prop = nec->key.prop;
-       int length = nec->base_snapshot.length;
-
-       /* Use unit quaternion for quaternion properties. */
-       if (nec->mix_mode == NEC_MIX_QUATERNION) {
-               unit_qt(r_values);
-               return;
-       }
-       /* Use all zero for Axis-Angle properties. */
-       if (nec->mix_mode == NEC_MIX_AXIS_ANGLE) {
-               zero_v4(r_values);
-               return;
-       }
-
-       /* NOTE: while this doesn't work for all RNA properties as default values aren't in fact
-        * set properly for most of them, at least the common ones (which also happen to get used
-        * in NLA strips a lot, e.g. scale) are set correctly.
-        */
-       if (RNA_property_array_check(prop)) {
-               BLI_assert(length == RNA_property_array_length(ptr, prop));
-               bool *tmp_bool;
-               int *tmp_int;
-
-               switch (RNA_property_type(prop)) {
-                       case PROP_BOOLEAN:
-                               tmp_bool = MEM_malloc_arrayN(sizeof(*tmp_bool), length, __func__);
-                               RNA_property_boolean_get_default_array(ptr, prop, tmp_bool);
-                               for (int i = 0; i < length; i++) {
-                                       r_values[i] = (float)tmp_bool[i];
-                               }
-                               MEM_freeN(tmp_bool);
-                               break;
-                       case PROP_INT:
-                               tmp_int = MEM_malloc_arrayN(sizeof(*tmp_int), length, __func__);
-                               RNA_property_int_get_default_array(ptr, prop, tmp_int);
-                               for (int i = 0; i < length; i++) {
-                                       r_values[i] = (float)tmp_int[i];
-                               }
-                               MEM_freeN(tmp_int);
-                               break;
-                       case PROP_FLOAT:
-                               RNA_property_float_get_default_array(ptr, prop, r_values);
-                               break;
-                       default:
-                               memset(r_values, 0, sizeof(float) * length);
-               }
-       }
-       else {
-               BLI_assert(length == 1);
-
-               switch (RNA_property_type(prop)) {
-                       case PROP_BOOLEAN:
-                               *r_values = (float)RNA_property_boolean_get_default(ptr, prop);
-                               break;
-                       case PROP_INT:
-                               *r_values = (float)RNA_property_int_get_default(ptr, prop);
-                               break;
-                       case PROP_FLOAT:
-                               *r_values = RNA_property_float_get_default(ptr, prop);
-                               break;
-                       case PROP_ENUM:
-                               *r_values = (float)RNA_property_enum_get_default(ptr, prop);
-                               break;
-                       default:
-                               *r_values = 0.0f;
-               }
-       }
-
-       /* Ensure multiplicative properties aren't reset to 0. */
-       if (nec->mix_mode == NEC_MIX_MULTIPLY) {
-               for (int i = 0; i < length; i++) {
-                       if (r_values[i] == 0.0f) {
-                               r_values[i] = 1.0f;
-                       }
-               }
-       }
+  PointerRNA *ptr = &nec->key.ptr;
+  PropertyRNA *prop = nec->key.prop;
+  int length = nec->base_snapshot.length;
+
+  /* Use unit quaternion for quaternion properties. */
+  if (nec->mix_mode == NEC_MIX_QUATERNION) {
+    unit_qt(r_values);
+    return;
+  }
+  /* Use all zero for Axis-Angle properties. */
+  if (nec->mix_mode == NEC_MIX_AXIS_ANGLE) {
+    zero_v4(r_values);
+    return;
+  }
+
+  /* NOTE: while this doesn't work for all RNA properties as default values aren't in fact
+   * set properly for most of them, at least the common ones (which also happen to get used
+   * in NLA strips a lot, e.g. scale) are set correctly.
+   */
+  if (RNA_property_array_check(prop)) {
+    BLI_assert(length == RNA_property_array_length(ptr, prop));
+    bool *tmp_bool;
+    int *tmp_int;
+
+    switch (RNA_property_type(prop)) {
+      case PROP_BOOLEAN:
+        tmp_bool = MEM_malloc_arrayN(sizeof(*tmp_bool), length, __func__);
+        RNA_property_boolean_get_default_array(ptr, prop, tmp_bool);
+        for (int i = 0; i < length; i++) {
+          r_values[i] = (float)tmp_bool[i];
+        }
+        MEM_freeN(tmp_bool);
+        break;
+      case PROP_INT:
+        tmp_int = MEM_malloc_arrayN(sizeof(*tmp_int), length, __func__);
+        RNA_property_int_get_default_array(ptr, prop, tmp_int);
+        for (int i = 0; i < length; i++) {
+          r_values[i] = (float)tmp_int[i];
+        }
+        MEM_freeN(tmp_int);
+        break;
+      case PROP_FLOAT:
+        RNA_property_float_get_default_array(ptr, prop, r_values);
+        break;
+      default:
+        memset(r_values, 0, sizeof(float) * length);
+    }
+  }
+  else {
+    BLI_assert(length == 1);
+
+    switch (RNA_property_type(prop)) {
+      case PROP_BOOLEAN:
+        *r_values = (float)RNA_property_boolean_get_default(ptr, prop);
+        break;
+      case PROP_INT:
+        *r_values = (float)RNA_property_int_get_default(ptr, prop);
+        break;
+      case PROP_FLOAT:
+        *r_values = RNA_property_float_get_default(ptr, prop);
+        break;
+      case PROP_ENUM:
+        *r_values = (float)RNA_property_enum_get_default(ptr, prop);
+        break;
+      default:
+        *r_values = 0.0f;
+    }
+  }
+
+  /* Ensure multiplicative properties aren't reset to 0. */
+  if (nec->mix_mode == NEC_MIX_MULTIPLY) {
+    for (int i = 0; i < length; i++) {
+      if (r_values[i] == 0.0f) {
+        r_values[i] = 1.0f;
+      }
+    }
+  }
 }
 
 static char nlaevalchan_detect_mix_mode(NlaEvalChannelKey *key, int length)
 {
-       PropertySubType subtype = RNA_property_subtype(key->prop);
+  PropertySubType subtype = RNA_property_subtype(key->prop);
 
-       if (subtype == PROP_QUATERNION && length == 4) {
-               return NEC_MIX_QUATERNION;
-       }
-       else if (subtype == PROP_AXISANGLE && length == 4) {
-               return NEC_MIX_AXIS_ANGLE;
-       }
-       else if (RNA_property_flag(key->prop) & PROP_PROPORTIONAL) {
-               return NEC_MIX_MULTIPLY;
-       }
-       else {
-               return NEC_MIX_ADD;
-       }
+  if (subtype == PROP_QUATERNION && length == 4) {
+    return NEC_MIX_QUATERNION;
+  }
+  else if (subtype == PROP_AXISANGLE && length == 4) {
+    return NEC_MIX_AXIS_ANGLE;
+  }
+  else if (RNA_property_flag(key->prop) & PROP_PROPORTIONAL) {
+    return NEC_MIX_MULTIPLY;
+  }
+  else {
+    return NEC_MIX_ADD;
+  }
 }
 
 /* Verify that an appropriate NlaEvalChannel for this property exists. */
-static NlaEvalChannel *nlaevalchan_verify_key(NlaEvalData *nlaeval, const char *path, NlaEvalChannelKey *key)
+static NlaEvalChannel *nlaevalchan_verify_key(NlaEvalData *nlaeval,
+                                              const char *path,
+                                              NlaEvalChannelKey *key)
 {
-       /* Look it up in the key hash. */
-       NlaEvalChannel **p_key_nec;
-       NlaEvalChannelKey **p_key;
-       bool found_key = BLI_ghash_ensure_p_ex(nlaeval->key_hash, key, (void ***)&p_key, (void ***)&p_key_nec);
+  /* Look it up in the key hash. */
+  NlaEvalChannel **p_key_nec;
+  NlaEvalChannelKey **p_key;
+  bool found_key = BLI_ghash_ensure_p_ex(
+      nlaeval->key_hash, key, (void ***)&p_key, (void ***)&p_key_nec);
 
-       if (found_key) {
-               return *p_key_nec;
-       }
+  if (found_key) {
+    return *p_key_nec;
+  }
 
-       /* Create the channel. */
-       bool is_array = RNA_property_array_check(key->prop);
-       int length = is_array ? RNA_property_array_length(&key->ptr, key->prop) : 1;
+  /* Create the channel. */
+  bool is_array = RNA_property_array_check(key->prop);
+  int length = is_array ? RNA_property_array_length(&key->ptr, key->prop) : 1;
 
-       NlaEvalChannel *nec = MEM_callocN(sizeof(NlaEvalChannel) + sizeof(float) * length, "NlaEvalChannel");
+  NlaEvalChannel *nec = MEM_callocN(sizeof(NlaEvalChannel) + sizeof(float) * length,
+                                    "NlaEvalChannel");
 
-       /* Initialize the channel. */
-       nec->rna_path = path;
-       nec->key = *key;
+  /* Initialize the channel. */
+  nec->rna_path = path;
+  nec->key = *key;
 
-       nec->owner = nlaeval;
-       nec->index = nlaeval->num_channels++;
-       nec->is_array = is_array;
+  nec->owner = nlaeval;
+  nec->index = nlaeval->num_channels++;
+  nec->is_array = is_array;
 
-       nec->mix_mode = nlaevalchan_detect_mix_mode(key, length);
+  nec->mix_mode = nlaevalchan_detect_mix_mode(key, length);
 
-       nlavalidmask_init(&nec->valid, length);
+  nlavalidmask_init(&nec->valid, length);
 
-       nec->base_snapshot.channel = nec;
-       nec->base_snapshot.length = length;
-       nec->base_snapshot.is_base = true;
+  nec->base_snapshot.channel = nec;
+  nec->base_snapshot.length = length;
+  nec->base_snapshot.is_base = true;
 
-       nlaevalchan_get_default_values(nec, nec->base_snapshot.values);
+  nlaevalchan_get_default_values(nec, nec->base_snapshot.values);
 
-       /* Store channel in data structures. */
-       BLI_addtail(&nlaeval->channels, nec);
+  /* Store channel in data structures. */
+  BLI_addtail(&nlaeval->channels, nec);
 
-       *nlaeval_snapshot_ensure_slot(&nlaeval->base_snapshot, nec) = &nec->base_snapshot;
+  *nlaeval_snapshot_ensure_slot(&nlaeval->base_snapshot, nec) = &nec->base_snapshot;
 
-       *p_key_nec = nec;
-       *p_key = &nec->key;
+  *p_key_nec = nec;
+  *p_key = &nec->key;
 
-       return nec;
+  return nec;
 }
 
 /* Verify that an appropriate NlaEvalChannel for this path exists. */
 static NlaEvalChannel *nlaevalchan_verify(PointerRNA *ptr, NlaEvalData *nlaeval, const char *path)
 {
-       if (path == NULL) {
-               return NULL;
-       }
+  if (path == NULL) {
+    return NULL;
+  }
 
-       /* Lookup the path in the path based hash. */
-       NlaEvalChannel **p_path_nec;
-       bool found_path = BLI_ghash_ensure_p(nlaeval->path_hash, (void *)path, (void ***)&p_path_nec);
+  /* Lookup the path in the path based hash. */
+  NlaEvalChannel **p_path_nec;
+  bool found_path = BLI_ghash_ensure_p(nlaeval->path_hash, (void *)path, (void ***)&p_path_nec);
 
-       if (found_path) {
-               return *p_path_nec;
-       }
+  if (found_path) {
+    return *p_path_nec;
+  }
 
-       /* Resolve the property and look it up in the key hash. */
-       NlaEvalChannelKey key;
+  /* Cache NULL result for now. */
+  *p_path_nec = NULL;
 
-       if (!RNA_path_resolve_property(ptr, path, &key.ptr, &key.prop)) {
-               /* Report failure to resolve the path. */
-               if (G.debug & G_DEBUG) {
-                       CLOG_WARN(&LOG, "Animato: Invalid path. ID = '%s',  '%s'",
-                                 (ptr->id.data) ? (((ID *)ptr->id.data)->name + 2) : "<No ID>", path);
-               }
+  /* Resolve the property and look it up in the key hash. */
+  NlaEvalChannelKey key;
 
-               /* Cache NULL result. */
-               *p_path_nec = NULL;
-               return NULL;
-       }
+  if (!RNA_path_resolve_property(ptr, path, &key.ptr, &key.prop)) {
+    /* Report failure to resolve the path. */
+    if (G.debug & G_DEBUG) {
+      CLOG_WARN(&LOG,
+                "Animato: Invalid path. ID = '%s',  '%s'",
+                (ptr->id.data) ? (((ID *)ptr->id.data)->name + 2) : "<No ID>",
+                path);
+    }
 
-       NlaEvalChannel *nec = nlaevalchan_verify_key(nlaeval, path, &key);
+    return NULL;
+  }
 
-       if (nec->rna_path == NULL) {
-               nec->rna_path = path;
-       }
+  /* Check that the property can be animated. */
+  if (ptr->id.data != NULL && !RNA_property_animateable(&key.ptr, key.prop)) {
+    return NULL;
+  }
 
-       return *p_path_nec = nec;
+  NlaEvalChannel *nec = nlaevalchan_verify_key(nlaeval, path, &key);
+
+  if (nec->rna_path == NULL) {
+    nec->rna_path = path;
+  }
+
+  return *p_path_nec = nec;
 }
 
 /* ---------------------- */
@@ -2447,307 +2629,333 @@ static NlaEvalChannel *nlaevalchan_verify(PointerRNA *ptr, NlaEvalData *nlaeval,
 /* accumulate the old and new values of a channel according to mode and influence */
 static float nla_blend_value(int blendmode, float old_value, float value, float inf)
 {
-       /* optimisation: no need to try applying if there is no influence */
-       if (IS_EQF(inf, 0.0f)) {
-               return old_value;
-       }
-
-       /* perform blending */
-       switch (blendmode) {
-               case NLASTRIP_MODE_ADD:
-                       /* simply add the scaled value on to the stack */
-                       return old_value + (value * inf);
-
-               case NLASTRIP_MODE_SUBTRACT:
-                       /* simply subtract the scaled value from the stack */
-                       return old_value - (value * inf);
-
-               case NLASTRIP_MODE_MULTIPLY:
-                       /* multiply the scaled value with the stack */
-                       /* Formula Used:
-                        *     result = fac * (a * b) + (1 - fac) * a
-                        */
-                       return inf * (old_value * value)  +   (1 - inf) * old_value;
-
-               case NLASTRIP_MODE_COMBINE:
-                       BLI_assert(!"combine mode");
-                       ATTR_FALLTHROUGH;
-
-               case NLASTRIP_MODE_REPLACE:
-               default: /* TODO: do we really want to blend by default? it seems more uses might prefer add... */
-                       /* do linear interpolation
-                        * - the influence of the accumulated data (elsewhere, that is called dstweight)
-                        *   is 1 - influence, since the strip's influence is srcweight
-                        */
-                       return old_value * (1.0f - inf)   +   (value * inf);
-       }
+  /* optimisation: no need to try applying if there is no influence */
+  if (IS_EQF(inf, 0.0f)) {
+    return old_value;
+  }
+
+  /* perform blending */
+  switch (blendmode) {
+    case NLASTRIP_MODE_ADD:
+      /* simply add the scaled value on to the stack */
+      return old_value + (value * inf);
+
+    case NLASTRIP_MODE_SUBTRACT:
+      /* simply subtract the scaled value from the stack */
+      return old_value - (value * inf);
+
+    case NLASTRIP_MODE_MULTIPLY:
+      /* multiply the scaled value with the stack */
+      /* Formula Used:
+       *     result = fac * (a * b) + (1 - fac) * a
+       */
+      return inf * (old_value * value) + (1 - inf) * old_value;
+
+    case NLASTRIP_MODE_COMBINE:
+      BLI_assert(!"combine mode");
+      ATTR_FALLTHROUGH;
+
+    case NLASTRIP_MODE_REPLACE:
+    default
+        : /* TODO: do we really want to blend by default? it seems more uses might prefer add... */
+      /* do linear interpolation
+       * - the influence of the accumulated data (elsewhere, that is called dstweight)
+       *   is 1 - influence, since the strip's influence is srcweight
+       */
+      return old_value * (1.0f - inf) + (value * inf);
+  }
 }
 
 /* accumulate the old and new values of a channel according to mode and influence */
-static float nla_combine_value(int mix_mode, float base_value, float old_value, float value, float inf)
+static float nla_combine_value(
+    int mix_mode, float base_value, float old_value, float value, float inf)
 {
-       /* optimisation: no need to try applying if there is no influence */
-       if (IS_EQF(inf, 0.0f)) {
-               return old_value;
-       }
+  /* optimisation: no need to try applying if there is no influence */
+  if (IS_EQF(inf, 0.0f)) {
+    return old_value;
+  }
 
-       /* perform blending */
-       switch (mix_mode) {
-               case NEC_MIX_ADD:
-               case NEC_MIX_AXIS_ANGLE:
-                       return old_value + (value - base_value) * inf;
+  /* perform blending */
+  switch (mix_mode) {
+    case NEC_MIX_ADD:
+    case NEC_MIX_AXIS_ANGLE:
+      return old_value + (value - base_value) * inf;
 
-               case NEC_MIX_MULTIPLY:
-                       if (base_value == 0.0f) {
-                               base_value = 1.0f;
-                       }
-                       return old_value * powf(value / base_value, inf);
+    case NEC_MIX_MULTIPLY:
+      if (base_value == 0.0f) {
+        base_value = 1.0f;
+      }
+      return old_value * powf(value / base_value, inf);
 
-               case NEC_MIX_QUATERNION:
-               default:
-                       BLI_assert(!"invalid mix mode");
-                       return old_value;
-       }
+    case NEC_MIX_QUATERNION:
+    default:
+      BLI_assert(!"invalid mix mode");
+      return old_value;
+  }
 }
 
 /* compute the value that would blend to the desired target value using nla_blend_value */
-static bool nla_invert_blend_value(int blend_mode, float old_value, float target_value, float influence, float *r_value)
-{
-       switch (blend_mode) {
-               case NLASTRIP_MODE_ADD:
-                       *r_value = (target_value - old_value) / influence;
-                       return true;
-
-               case NLASTRIP_MODE_SUBTRACT:
-                       *r_value = (old_value - target_value) / influence;
-                       return true;
-
-               case NLASTRIP_MODE_MULTIPLY:
-                       if (old_value == 0.0f) {
-                               /* Resolve 0/0 to 1. */
-                               if (target_value == 0.0f) {
-                                       *r_value = 1.0f;
-                                       return true;
-                               }
-                               /* Division by zero. */
-                               return false;
-                       }
-                       else {
-                               *r_value = (target_value - old_value) / influence / old_value + 1.0f;
-                               return true;
-                       }
-
-               case NLASTRIP_MODE_COMBINE:
-                       BLI_assert(!"combine mode");
-                       ATTR_FALLTHROUGH;
-
-               case NLASTRIP_MODE_REPLACE:
-               default:
-                       *r_value = (target_value - old_value) / influence + old_value;
-                       return true;
-       }
+static bool nla_invert_blend_value(
+    int blend_mode, float old_value, float target_value, float influence, float *r_value)
+{
+  switch (blend_mode) {
+    case NLASTRIP_MODE_ADD:
+      *r_value = (target_value - old_value) / influence;
+      return true;
+
+    case NLASTRIP_MODE_SUBTRACT:
+      *r_value = (old_value - target_value) / influence;
+      return true;
+
+    case NLASTRIP_MODE_MULTIPLY:
+      if (old_value == 0.0f) {
+        /* Resolve 0/0 to 1. */
+        if (target_value == 0.0f) {
+          *r_value = 1.0f;
+          return true;
+        }
+        /* Division by zero. */
+        return false;
+      }
+      else {
+        *r_value = (target_value - old_value) / influence / old_value + 1.0f;
+        return true;
+      }
+
+    case NLASTRIP_MODE_COMBINE:
+      BLI_assert(!"combine mode");
+      ATTR_FALLTHROUGH;
+
+    case NLASTRIP_MODE_REPLACE:
+    default:
+      *r_value = (target_value - old_value) / influence + old_value;
+      return true;
+  }
 }
 
 /* compute the value that would blend to the desired target value using nla_combine_value */
-static bool nla_invert_combine_value(int mix_mode, float base_value, float old_value, float target_value, float influence, float *r_value)
-{
-       switch (mix_mode) {
-               case NEC_MIX_ADD:
-               case NEC_MIX_AXIS_ANGLE:
-                       *r_value = base_value + (target_value - old_value) / influence;
-                       return true;
-
-               case NEC_MIX_MULTIPLY:
-                       if (base_value == 0.0f) {
-                               base_value = 1.0f;
-                       }
-                       if (old_value == 0.0f) {
-                               /* Resolve 0/0 to 1. */
-                               if (target_value == 0.0f) {
-                                       *r_value = base_value;
-                                       return true;
-                               }
-                               /* Division by zero. */
-                               return false;
-                       }
-                       else {
-                               *r_value = base_value * powf(target_value / old_value, 1.0f / influence);
-                               return true;
-                       }
-
-               case NEC_MIX_QUATERNION:
-               default:
-                       BLI_assert(!"invalid mix mode");
-                       return false;
-       }
+static bool nla_invert_combine_value(int mix_mode,
+                                     float base_value,
+                                     float old_value,
+                                     float target_value,
+                                     float influence,
+                                     float *r_value)
+{
+  switch (mix_mode) {
+    case NEC_MIX_ADD:
+    case NEC_MIX_AXIS_ANGLE:
+      *r_value = base_value + (target_value - old_value) / influence;
+      return true;
+
+    case NEC_MIX_MULTIPLY:
+      if (base_value == 0.0f) {
+        base_value = 1.0f;
+      }
+      if (old_value == 0.0f) {
+        /* Resolve 0/0 to 1. */
+        if (target_value == 0.0f) {
+          *r_value = base_value;
+          return true;
+        }
+        /* Division by zero. */
+        return false;
+      }
+      else {
+        *r_value = base_value * powf(target_value / old_value, 1.0f / influence);
+        return true;
+      }
+
+    case NEC_MIX_QUATERNION:
+    default:
+      BLI_assert(!"invalid mix mode");
+      return false;
+  }
 }
 
 /* accumulate quaternion channels for Combine mode according to influence */
-static void nla_combine_quaternion(const float old_values[4], const float values[4], float influence, float result[4])
+static void nla_combine_quaternion(const float old_values[4],
+                                   const float values[4],
+                                   float influence,
+                                   float result[4])
 {
-       float tmp_old[4], tmp_new[4];
+  float tmp_old[4], tmp_new[4];
 
-       normalize_qt_qt(tmp_old, old_values);
-       normalize_qt_qt(tmp_new, values);
+  normalize_qt_qt(tmp_old, old_values);
+  normalize_qt_qt(tmp_new, values);
 
-       pow_qt_fl_normalized(tmp_new, influence);
-       mul_qt_qtqt(result, tmp_old, tmp_new);
+  pow_qt_fl_normalized(tmp_new, influence);
+  mul_qt_qtqt(result, tmp_old, tmp_new);
 }
 
 /* invert accumulation of quaternion channels for Combine mode according to influence */
-static void nla_invert_combine_quaternion(const float old_values[4], const float values[4], float influence, float result[4])
+static void nla_invert_combine_quaternion(const float old_values[4],
+                                          const float values[4],
+                                          float influence,
+                                          float result[4])
 {
-       float tmp_old[4], tmp_new[4];
+  float tmp_old[4], tmp_new[4];
 
-       normalize_qt_qt(tmp_old, old_values);
-       normalize_qt_qt(tmp_new, values);
-       invert_qt_normalized(tmp_old);
+  normalize_qt_qt(tmp_old, old_values);
+  normalize_qt_qt(tmp_new, values);
+  invert_qt_normalized(tmp_old);
 
-       mul_qt_qtqt(result, tmp_old, tmp_new);
-       pow_qt_fl_normalized(result, 1.0f / influence);
+  mul_qt_qtqt(result, tmp_old, tmp_new);
+  pow_qt_fl_normalized(result, 1.0f / influence);
 }
 
 /* Data about the current blend mode. */
 typedef struct NlaBlendData {
-       NlaEvalSnapshot *snapshot;
-       int mode;
-       float influence;
+  NlaEvalSnapshot *snapshot;
+  int mode;
+  float influence;
 
-       NlaEvalChannel *blend_queue;
+  NlaEvalChannel *blend_queue;
 } NlaBlendData;
 
 /* Queue the channel for deferred blending. */
 static NlaEvalChannelSnapshot *nlaevalchan_queue_blend(NlaBlendData *blend, NlaEvalChannel *nec)
 {
-       if (!nec->in_blend) {
-               if (nec->blend_snapshot == NULL) {
-                       nec->blend_snapshot = nlaevalchan_snapshot_new(nec);
-               }
+  if (!nec->in_blend) {
+    if (nec->blend_snapshot == NULL) {
+      nec->blend_snapshot = nlaevalchan_snapshot_new(nec);
+    }
 
-               nec->in_blend = true;
-               nlaevalchan_snapshot_copy(nec->blend_snapshot, &nec->base_snapshot);
+    nec->in_blend = true;
+    nlaevalchan_snapshot_copy(nec->blend_snapshot, &nec->base_snapshot);
 
-               nec->next_blend = blend->blend_queue;
-               blend->blend_queue = nec;
-       }
+    nec->next_blend = blend->blend_queue;
+    blend->blend_queue = nec;
+  }
 
-       return nec->blend_snapshot;
+  return nec->blend_snapshot;
 }
 
 /* Accumulate (i.e. blend) the given value on to the channel it affects. */
-static bool nlaeval_blend_value(NlaBlendData *blend, NlaEvalChannel *nec, int array_index, float value)
-{
-       if (nec == NULL) {
-               return false;
-       }
-
-       int index = nlaevalchan_validate_index(nec, array_index);
-
-       if (index < 0) {
-               if (G.debug & G_DEBUG) {
-                       ID *id = nec->key.ptr.id.data;
-                       CLOG_WARN(&LOG, "Animato: Invalid array index. ID = '%s',  '%s[%d]', array length is %d",
-                         id ? (id->name + 2) : "<No ID>", nec->rna_path, array_index, nec->base_snapshot.length);
-               }
-
-               return false;
-       }
-
-       if (nec->mix_mode == NEC_MIX_QUATERNION) {
-               /* For quaternion properties, always output all sub-channels. */
-               BLI_bitmap_set_all(nec->valid.ptr, true, 4);
-       }
-       else {
-               BLI_BITMAP_ENABLE(nec->valid.ptr, index);
-       }
-
-       NlaEvalChannelSnapshot *nec_snapshot = nlaeval_snapshot_ensure_channel(blend->snapshot, nec);
-       float *p_value = &nec_snapshot->values[index];
-
-       if (blend->mode == NLASTRIP_MODE_COMBINE) {
-               /* Quaternion blending is deferred until all sub-channel values are known. */
-               if (nec->mix_mode == NEC_MIX_QUATERNION) {
-                       NlaEvalChannelSnapshot *blend_snapshot = nlaevalchan_queue_blend(blend, nec);
-
-                       blend_snapshot->values[index] = value;
-               }
-               else {
-                       float base_value = nec->base_snapshot.values[index];
-
-                       *p_value = nla_combine_value(nec->mix_mode, base_value, *p_value, value, blend->influence);
-               }
-       }
-       else {
-               *p_value = nla_blend_value(blend->mode, *p_value, value, blend->influence);
-       }
-
-       return true;
+static bool nlaeval_blend_value(NlaBlendData *blend,
+                                NlaEvalChannel *nec,
+                                int array_index,
+                                float value)
+{
+  if (nec == NULL) {
+    return false;
+  }
+
+  int index = nlaevalchan_validate_index(nec, array_index);
+
+  if (index < 0) {
+    if (G.debug & G_DEBUG) {
+      ID *id = nec->key.ptr.id.data;
+      CLOG_WARN(&LOG,
+                "Animato: Invalid array index. ID = '%s',  '%s[%d]', array length is %d",
+                id ? (id->name + 2) : "<No ID>",
+                nec->rna_path,
+                array_index,
+                nec->base_snapshot.length);
+    }
+
+    return false;
+  }
+
+  if (nec->mix_mode == NEC_MIX_QUATERNION) {
+    /* For quaternion properties, always output all sub-channels. */
+    BLI_bitmap_set_all(nec->valid.ptr, true, 4);
+  }
+  else {
+    BLI_BITMAP_ENABLE(nec->valid.ptr, index);
+  }
+
+  NlaEvalChannelSnapshot *nec_snapshot = nlaeval_snapshot_ensure_channel(blend->snapshot, nec);
+  float *p_value = &nec_snapshot->values[index];
+
+  if (blend->mode == NLASTRIP_MODE_COMBINE) {
+    /* Quaternion blending is deferred until all sub-channel values are known. */
+    if (nec->mix_mode == NEC_MIX_QUATERNION) {
+      NlaEvalChannelSnapshot *blend_snapshot = nlaevalchan_queue_blend(blend, nec);
+
+      blend_snapshot->values[index] = value;
+    }
+    else {
+      float base_value = nec->base_snapshot.values[index];
+
+      *p_value = nla_combine_value(nec->mix_mode, base_value, *p_value, value, blend->influence);
+    }
+  }
+  else {
+    *p_value = nla_blend_value(blend->mode, *p_value, value, blend->influence);
+  }
+
+  return true;
 }
 
 /* Finish deferred quaternion blending. */
 static void nlaeval_blend_flush(NlaBlendData *blend)
 {
-       NlaEvalChannel *nec;
+  NlaEvalChannel *nec;
 
-       while ((nec = blend->blend_queue)) {
-               blend->blend_queue = nec->next_blend;
-               nec->in_blend = false;
+  while ((nec = blend->blend_queue)) {
+    blend->blend_queue = nec->next_blend;
+    nec->in_blend = false;
 
-               NlaEvalChannelSnapshot *nec_snapshot = nlaeval_snapshot_ensure_channel(blend->snapshot, nec);
-               NlaEvalChannelSnapshot *blend_snapshot = nec->blend_snapshot;
+    NlaEvalChannelSnapshot *nec_snapshot = nlaeval_snapshot_ensure_channel(blend->snapshot, nec);
+    NlaEvalChannelSnapshot *blend_snapshot = nec->blend_snapshot;
 
-               if (nec->mix_mode == NEC_MIX_QUATERNION) {
-                       nla_combine_quaternion(nec_snapshot->values, blend_snapshot->values, blend->influence, nec_snapshot->values);
-               }
-               else {
-                       BLI_assert(!"mix quaternion");
-               }
-       }
+    if (nec->mix_mode == NEC_MIX_QUATERNION) {
+      nla_combine_quaternion(
+          nec_snapshot->values, blend_snapshot->values, blend->influence, nec_snapshot->values);
+    }
+    else {
+      BLI_assert(!"mix quaternion");
+    }
+  }
 }
 
 /* Blend the specified snapshots into the target, and free the input snapshots. */
-static void nlaeval_snapshot_mix_and_free(NlaEvalData *nlaeval, NlaEvalSnapshot *out, NlaEvalSnapshot *in1, NlaEvalSnapshot *in2, float alpha)
-{
-       BLI_assert(in1->base == out && in2->base == out);
-
-       nlaeval_snapshot_ensure_size(out, nlaeval->num_channels);
-
-       for (int i = 0; i < nlaeval->num_channels; i++) {
-               NlaEvalChannelSnapshot *c_in1 = nlaeval_snapshot_get(in1, i);
-               NlaEvalChannelSnapshot *c_in2 = nlaeval_snapshot_get(in2, i);
-
-               if (c_in1 || c_in2) {
-                       NlaEvalChannelSnapshot *c_out = out->channels[i];
-
-                       /* Steal the entry from one of the input snapshots. */
-                       if (c_out == NULL) {
-                               if (c_in1 != NULL) {
-                                       c_out = c_in1;
-                                       in1->channels[i] = NULL;
-                               }
-                               else {
-                                       c_out = c_in2;
-                                       in2->channels[i] = NULL;
-                               }
-                       }
-
-                       if (c_in1 == NULL) {
-                               c_in1 = nlaeval_snapshot_find_channel(in1->base, c_out->channel);
-                       }
-                       if (c_in2 == NULL) {
-                               c_in2 = nlaeval_snapshot_find_channel(in2->base, c_out->channel);
-                       }
-
-                       out->channels[i] = c_out;
-
-                       for (int j = 0; j < c_out->length; j++) {
-                               c_out->values[j] = c_in1->values[j] * (1.0f - alpha) + c_in2->values[j] * alpha;
-                       }
-               }
-       }
-
-       nlaeval_snapshot_free_data(in1);
-       nlaeval_snapshot_free_data(in2);
+static void nlaeval_snapshot_mix_and_free(NlaEvalData *nlaeval,
+                                          NlaEvalSnapshot *out,
+                                          NlaEvalSnapshot *in1,
+                                          NlaEvalSnapshot *in2,
+                                          float alpha)
+{
+  BLI_assert(in1->base == out && in2->base == out);
+
+  nlaeval_snapshot_ensure_size(out, nlaeval->num_channels);
+
+  for (int i = 0; i < nlaeval->num_channels; i++) {
+    NlaEvalChannelSnapshot *c_in1 = nlaeval_snapshot_get(in1, i);
+    NlaEvalChannelSnapshot *c_in2 = nlaeval_snapshot_get(in2, i);
+
+    if (c_in1 || c_in2) {
+      NlaEvalChannelSnapshot *c_out = out->channels[i];
+
+      /* Steal the entry from one of the input snapshots. */
+      if (c_out == NULL) {
+        if (c_in1 != NULL) {
+          c_out = c_in1;
+          in1->channels[i] = NULL;
+        }
+        else {
+          c_out = c_in2;
+          in2->channels[i] = NULL;
+        }
+      }
+
+      if (c_in1 == NULL) {
+        c_in1 = nlaeval_snapshot_find_channel(in1->base, c_out->channel);
+      }
+      if (c_in2 == NULL) {
+        c_in2 = nlaeval_snapshot_find_channel(in2->base, c_out->channel);
+      }
+
+      out->channels[i] = c_out;
+
+      for (int j = 0; j < c_out->length; j++) {
+        c_out->values[j] = c_in1->values[j] * (1.0f - alpha) + c_in2->values[j] * alpha;
+      }
+    }
+  }
+
+  nlaeval_snapshot_free_data(in1);
+  nlaeval_snapshot_free_data(in2);
 }
 
 /* ---------------------- */
@@ -2756,330 +2964,365 @@ static void nlaeval_snapshot_mix_and_free(NlaEvalData *nlaeval, NlaEvalSnapshot
 /* Temporarily join two lists of modifiers together, storing the result in a third list */
 static void nlaeval_fmodifiers_join_stacks(ListBase *result, ListBase *list1, ListBase *list2)
 {
-       FModifier *fcm1, *fcm2;
-
-       /* if list1 is invalid...  */
-       if (ELEM(NULL, list1, list1->first)) {
-               if (list2 && list2->first) {
-                       result->first = list2->first;
-                       result->last = list2->last;
-               }
-       }
-       /* if list 2 is invalid... */
-       else if (ELEM(NULL, list2, list2->first)) {
-               result->first = list1->first;
-               result->last = list1->last;
-       }
-       else {
-               /* list1 should be added first, and list2 second, with the endpoints of these being the endpoints for result
-                * - the original lists must be left unchanged though, as we need that fact for restoring
-                */
-               result->first = list1->first;
-               result->last = list2->last;
-
-               fcm1 = list1->last;
-               fcm2 = list2->first;
-
-               fcm1->next = fcm2;
-               fcm2->prev = fcm1;
-       }
+  FModifier *fcm1, *fcm2;
+
+  /* if list1 is invalid...  */
+  if (ELEM(NULL, list1, list1->first)) {
+    if (list2 && list2->first) {
+      result->first = list2->first;
+      result->last = list2->last;
+    }
+  }
+  /* if list 2 is invalid... */
+  else if (ELEM(NULL, list2, list2->first)) {
+    result->first = list1->first;
+    result->last = list1->last;
+  }
+  else {
+    /* list1 should be added first, and list2 second, with the endpoints of these being the endpoints for result
+     * - the original lists must be left unchanged though, as we need that fact for restoring
+     */
+    result->first = list1->first;
+    result->last = list2->last;
+
+    fcm1 = list1->last;
+    fcm2 = list2->first;
+
+    fcm1->next = fcm2;
+    fcm2->prev = fcm1;
+  }
 }
 
 /* Split two temporary lists of modifiers */
 static void nlaeval_fmodifiers_split_stacks(ListBase *list1, ListBase *list2)
 {
-       FModifier *fcm1, *fcm2;
+  FModifier *fcm1, *fcm2;
 
-       /* if list1/2 is invalid... just skip */
-       if (ELEM(NULL, list1, list2))
-               return;
-       if (ELEM(NULL, list1->first, list2->first))
-               return;
+  /* if list1/2 is invalid... just skip */
+  if (ELEM(NULL, list1, list2)) {
+    return;
+  }
+  if (ELEM(NULL, list1->first, list2->first)) {
+    return;
+  }
 
-       /* get endpoints */
-       fcm1 = list1->last;
-       fcm2 = list2->first;
+  /* get endpoints */
+  fcm1 = list1->last;
+  fcm2 = list2->first;
 
-       /* clear their links */
-       fcm1->next = NULL;
-       fcm2->prev = NULL;
+  /* clear their links */
+  fcm1->next = NULL;
+  fcm2->prev = NULL;
 }
 
 /* ---------------------- */
 
 /* evaluate action-clip strip */
-static void nlastrip_evaluate_actionclip(PointerRNA *ptr, NlaEvalData *channels, ListBase *modifiers, NlaEvalStrip *nes, NlaEvalSnapshot *snapshot)
-{
-       FModifierStackStorage *storage;
-       ListBase tmp_modifiers = {NULL, NULL};
-       NlaStrip *strip = nes->strip;
-       FCurve *fcu;
-       float evaltime;
-
-       /* sanity checks for action */
-       if (strip == NULL)
-               return;
-
-       if (strip->act == NULL) {
-               CLOG_ERROR(&LOG, "NLA-Strip Eval Error: Strip '%s' has no Action", strip->name);
-               return;
-       }
-
-       action_idcode_patch_check(ptr->id.data, strip->act);
-
-       /* join this strip's modifiers to the parent's modifiers (own modifiers first) */
-       nlaeval_fmodifiers_join_stacks(&tmp_modifiers, &strip->modifiers, modifiers);
-
-       /* evaluate strip's modifiers which modify time to evaluate the base curves at */
-       storage = evaluate_fmodifiers_storage_new(&tmp_modifiers);
-       evaltime = evaluate_time_fmodifiers(storage, &tmp_modifiers, NULL, 0.0f, strip->strip_time);
-
-       NlaBlendData blend = {
-           .snapshot = snapshot,
-           .mode = strip->blendmode,
-           .influence = strip->influence,
-       };
-
-       /* evaluate all the F-Curves in the action, saving the relevant pointers to data that will need to be used */
-       for (fcu = strip->act->curves.first; fcu; fcu = fcu->next) {
-               float value = 0.0f;
-
-               /* check if this curve should be skipped */
-               if (fcu->flag & (FCURVE_MUTED | FCURVE_DISABLED))
-                       continue;
-               if ((fcu->grp) && (fcu->grp->flag & AGRP_MUTED))
-                       continue;
-
-               /* evaluate the F-Curve's value for the time given in the strip
-                * NOTE: we use the modified time here, since strip's F-Curve Modifiers are applied on top of this
-                */
-               value = evaluate_fcurve(fcu, evaltime);
-
-               /* apply strip's F-Curve Modifiers on this value
-                * NOTE: we apply the strip's original evaluation time not the modified one (as per standard F-Curve eval)
-                */
-               evaluate_value_fmodifiers(storage, &tmp_modifiers, fcu, &value, strip->strip_time);
-
-               /* get an NLA evaluation channel to work with, and accumulate the evaluated value with the value(s)
-                * stored in this channel if it has been used already
-                */
-               NlaEvalChannel *nec = nlaevalchan_verify(ptr, channels, fcu->rna_path);
-
-               nlaeval_blend_value(&blend, nec, fcu->array_index, value);
-       }
-
-       nlaeval_blend_flush(&blend);
-
-       /* free temporary storage */
-       evaluate_fmodifiers_storage_free(storage);
-
-       /* unlink this strip's modifiers from the parent's modifiers again */
-       nlaeval_fmodifiers_split_stacks(&strip->modifiers, modifiers);
+static void nlastrip_evaluate_actionclip(PointerRNA *ptr,
+                                         NlaEvalData *channels,
+                                         ListBase *modifiers,
+                                         NlaEvalStrip *nes,
+                                         NlaEvalSnapshot *snapshot)
+{
+  ListBase tmp_modifiers = {NULL, NULL};
+  NlaStrip *strip = nes->strip;
+  FCurve *fcu;
+  float evaltime;
+
+  /* sanity checks for action */
+  if (strip == NULL) {
+    return;
+  }
+
+  if (strip->act == NULL) {
+    CLOG_ERROR(&LOG, "NLA-Strip Eval Error: Strip '%s' has no Action", strip->name);
+    return;
+  }
+
+  action_idcode_patch_check(ptr->id.data, strip->act);
+
+  /* join this strip's modifiers to the parent's modifiers (own modifiers first) */
+  nlaeval_fmodifiers_join_stacks(&tmp_modifiers, &strip->modifiers, modifiers);
+
+  /* evaluate strip's modifiers which modify time to evaluate the base curves at */
+  FModifiersStackStorage storage;
+  storage.modifier_count = BLI_listbase_count(&tmp_modifiers);
+  storage.size_per_modifier = evaluate_fmodifiers_storage_size_per_modifier(&tmp_modifiers);
+  storage.buffer = alloca(storage.modifier_count * storage.size_per_modifier);
+
+  evaltime = evaluate_time_fmodifiers(&storage, &tmp_modifiers, NULL, 0.0f, strip->strip_time);
+
+  NlaBlendData blend = {
+      .snapshot = snapshot,
+      .mode = strip->blendmode,
+      .influence = strip->influence,
+  };
+
+  /* evaluate all the F-Curves in the action, saving the relevant pointers to data that will need to be used */
+  for (fcu = strip->act->curves.first; fcu; fcu = fcu->next) {
+    float value = 0.0f;
+
+    /* check if this curve should be skipped */
+    if (fcu->flag & (FCURVE_MUTED | FCURVE_DISABLED)) {
+      continue;
+    }
+    if ((fcu->grp) && (fcu->grp->flag & AGRP_MUTED)) {
+      continue;
+    }
+
+    /* evaluate the F-Curve's value for the time given in the strip
+     * NOTE: we use the modified time here, since strip's F-Curve Modifiers are applied on top of this
+     */
+    value = evaluate_fcurve(fcu, evaltime);
+
+    /* apply strip's F-Curve Modifiers on this value
+     * NOTE: we apply the strip's original evaluation time not the modified one (as per standard F-Curve eval)
+     */
+    evaluate_value_fmodifiers(&storage, &tmp_modifiers, fcu, &value, strip->strip_time);
+
+    /* get an NLA evaluation channel to work with, and accumulate the evaluated value with the value(s)
+     * stored in this channel if it has been used already
+     */
+    NlaEvalChannel *nec = nlaevalchan_verify(ptr, channels, fcu->rna_path);
+
+    nlaeval_blend_value(&blend, nec, fcu->array_index, value);
+  }
+
+  nlaeval_blend_flush(&blend);
+
+  /* unlink this strip's modifiers from the parent's modifiers again */
+  nlaeval_fmodifiers_split_stacks(&strip->modifiers, modifiers);
 }
 
 /* evaluate transition strip */
-static void nlastrip_evaluate_transition(
-        Depsgraph *depsgraph, PointerRNA *ptr, NlaEvalData *channels, ListBase *modifiers, NlaEvalStrip *nes, NlaEvalSnapshot *snapshot)
-{
-       ListBase tmp_modifiers = {NULL, NULL};
-       NlaEvalSnapshot snapshot1, snapshot2;
-       NlaEvalStrip tmp_nes;
-       NlaStrip *s1, *s2;
-
-       /* join this strip's modifiers to the parent's modifiers (own modifiers first) */
-       nlaeval_fmodifiers_join_stacks(&tmp_modifiers, &nes->strip->modifiers, modifiers);
-
-       /* get the two strips to operate on
-        * - we use the endpoints of the strips directly flanking our strip
-        *   using these as the endpoints of the transition (destination and source)
-        * - these should have already been determined to be valid...
-        * - if this strip is being played in reverse, we need to swap these endpoints
-        *   otherwise they will be interpolated wrong
-        */
-       if (nes->strip->flag & NLASTRIP_FLAG_REVERSE) {
-               s1 = nes->strip->next;
-               s2 = nes->strip->prev;
-       }
-       else {
-               s1 = nes->strip->prev;
-               s2 = nes->strip->next;
-       }
-
-       /* prepare template for 'evaluation strip'
-        * - based on the transition strip's evaluation strip data
-        * - strip_mode is NES_TIME_TRANSITION_* based on which endpoint
-        * - strip_time is the 'normalized' (i.e. in-strip) time for evaluation,
-        *   which doubles up as an additional weighting factor for the strip influences
-        *   which allows us to appear to be 'interpolating' between the two extremes
-        */
-       tmp_nes = *nes;
-
-       /* evaluate these strips into a temp-buffer (tmp_channels) */
-       /* FIXME: modifier evaluation here needs some work... */
-       /* first strip */
-       tmp_nes.strip_mode = NES_TIME_TRANSITION_START;
-       tmp_nes.strip = s1;
-       nlaeval_snapshot_init(&snapshot1, channels, snapshot);
-       nlastrip_evaluate(depsgraph, ptr, channels, &tmp_modifiers, &tmp_nes, &snapshot1);
-
-       /* second strip */
-       tmp_nes.strip_mode = NES_TIME_TRANSITION_END;
-       tmp_nes.strip = s2;
-       nlaeval_snapshot_init(&snapshot2, channels, snapshot);
-       nlastrip_evaluate(depsgraph, ptr, channels, &tmp_modifiers, &tmp_nes, &snapshot2);
-
-       /* accumulate temp-buffer and full-buffer, using the 'real' strip */
-       nlaeval_snapshot_mix_and_free(channels, snapshot, &snapshot1, &snapshot2, nes->strip_time);
-
-       /* unlink this strip's modifiers from the parent's modifiers again */
-       nlaeval_fmodifiers_split_stacks(&nes->strip->modifiers, modifiers);
+static void nlastrip_evaluate_transition(Depsgraph *depsgraph,
+                                         PointerRNA *ptr,
+                                         NlaEvalData *channels,
+                                         ListBase *modifiers,
+                                         NlaEvalStrip *nes,
+                                         NlaEvalSnapshot *snapshot)
+{
+  ListBase tmp_modifiers = {NULL, NULL};
+  NlaEvalSnapshot snapshot1, snapshot2;
+  NlaEvalStrip tmp_nes;
+  NlaStrip *s1, *s2;
+
+  /* join this strip's modifiers to the parent's modifiers (own modifiers first) */
+  nlaeval_fmodifiers_join_stacks(&tmp_modifiers, &nes->strip->modifiers, modifiers);
+
+  /* get the two strips to operate on
+   * - we use the endpoints of the strips directly flanking our strip
+   *   using these as the endpoints of the transition (destination and source)
+   * - these should have already been determined to be valid...
+   * - if this strip is being played in reverse, we need to swap these endpoints
+   *   otherwise they will be interpolated wrong
+   */
+  if (nes->strip->flag & NLASTRIP_FLAG_REVERSE) {
+    s1 = nes->strip->next;
+    s2 = nes->strip->prev;
+  }
+  else {
+    s1 = nes->strip->prev;
+    s2 = nes->strip->next;
+  }
+
+  /* prepare template for 'evaluation strip'
+   * - based on the transition strip's evaluation strip data
+   * - strip_mode is NES_TIME_TRANSITION_* based on which endpoint
+   * - strip_time is the 'normalized' (i.e. in-strip) time for evaluation,
+   *   which doubles up as an additional weighting factor for the strip influences
+   *   which allows us to appear to be 'interpolating' between the two extremes
+   */
+  tmp_nes = *nes;
+
+  /* evaluate these strips into a temp-buffer (tmp_channels) */
+  /* FIXME: modifier evaluation here needs some work... */
+  /* first strip */
+  tmp_nes.strip_mode = NES_TIME_TRANSITION_START;
+  tmp_nes.strip = s1;
+  nlaeval_snapshot_init(&snapshot1, channels, snapshot);
+  nlastrip_evaluate(depsgraph, ptr, channels, &tmp_modifiers, &tmp_nes, &snapshot1);
+
+  /* second strip */
+  tmp_nes.strip_mode = NES_TIME_TRANSITION_END;
+  tmp_nes.strip = s2;
+  nlaeval_snapshot_init(&snapshot2, channels, snapshot);
+  nlastrip_evaluate(depsgraph, ptr, channels, &tmp_modifiers, &tmp_nes, &snapshot2);
+
+  /* accumulate temp-buffer and full-buffer, using the 'real' strip */
+  nlaeval_snapshot_mix_and_free(channels, snapshot, &snapshot1, &snapshot2, nes->strip_time);
+
+  /* unlink this strip's modifiers from the parent's modifiers again */
+  nlaeval_fmodifiers_split_stacks(&nes->strip->modifiers, modifiers);
 }
 
 /* evaluate meta-strip */
-static void nlastrip_evaluate_meta(
-        Depsgraph *depsgraph, PointerRNA *ptr, NlaEvalData *channels, ListBase *modifiers, NlaEvalStrip *nes, NlaEvalSnapshot *snapshot)
-{
-       ListBase tmp_modifiers = {NULL, NULL};
-       NlaStrip *strip = nes->strip;
-       NlaEvalStrip *tmp_nes;
-       float evaltime;
-
-       /* meta-strip was calculated normally to have some time to be evaluated at
-        * and here we 'look inside' the meta strip, treating it as a decorated window to
-        * it's child strips, which get evaluated as if they were some tracks on a strip
-        * (but with some extra modifiers to apply).
-        *
-        * NOTE: keep this in sync with animsys_evaluate_nla()
-        */
-
-       /* join this strip's modifiers to the parent's modifiers (own modifiers first) */
-       nlaeval_fmodifiers_join_stacks(&tmp_modifiers, &strip->modifiers, modifiers);
-
-       /* find the child-strip to evaluate */
-       evaltime = (nes->strip_time * (strip->end - strip->start)) + strip->start;
-       tmp_nes = nlastrips_ctime_get_strip(depsgraph, NULL, &strip->strips, -1, evaltime);
-
-       /* directly evaluate child strip into accumulation buffer...
-        * - there's no need to use a temporary buffer (as it causes issues [T40082])
-        */
-       if (tmp_nes) {
-               nlastrip_evaluate(depsgraph, ptr, channels, &tmp_modifiers, tmp_nes, snapshot);
-
-               /* free temp eval-strip */
-               MEM_freeN(tmp_nes);
-       }
-
-       /* unlink this strip's modifiers from the parent's modifiers again */
-       nlaeval_fmodifiers_split_stacks(&strip->modifiers, modifiers);
+static void nlastrip_evaluate_meta(Depsgraph *depsgraph,
+                                   PointerRNA *ptr,
+                                   NlaEvalData *channels,
+                                   ListBase *modifiers,
+                                   NlaEvalStrip *nes,
+                                   NlaEvalSnapshot *snapshot)
+{
+  ListBase tmp_modifiers = {NULL, NULL};
+  NlaStrip *strip = nes->strip;
+  NlaEvalStrip *tmp_nes;
+  float evaltime;
+
+  /* meta-strip was calculated normally to have some time to be evaluated at
+   * and here we 'look inside' the meta strip, treating it as a decorated window to
+   * it's child strips, which get evaluated as if they were some tracks on a strip
+   * (but with some extra modifiers to apply).
+   *
+   * NOTE: keep this in sync with animsys_evaluate_nla()
+   */
+
+  /* join this strip's modifiers to the parent's modifiers (own modifiers first) */
+  nlaeval_fmodifiers_join_stacks(&tmp_modifiers, &strip->modifiers, modifiers);
+
+  /* find the child-strip to evaluate */
+  evaltime = (nes->strip_time * (strip->end - strip->start)) + strip->start;
+  tmp_nes = nlastrips_ctime_get_strip(depsgraph, NULL, &strip->strips, -1, evaltime);
+
+  /* directly evaluate child strip into accumulation buffer...
+   * - there's no need to use a temporary buffer (as it causes issues [T40082])
+   */
+  if (tmp_nes) {
+    nlastrip_evaluate(depsgraph, ptr, channels, &tmp_modifiers, tmp_nes, snapshot);
+
+    /* free temp eval-strip */
+    MEM_freeN(tmp_nes);
+  }
+
+  /* unlink this strip's modifiers from the parent's modifiers again */
+  nlaeval_fmodifiers_split_stacks(&strip->modifiers, modifiers);
 }
 
 /* evaluates the given evaluation strip */
-void nlastrip_evaluate(Depsgraph *depsgraph, PointerRNA *ptr, NlaEvalData *channels, ListBase *modifiers, NlaEvalStrip *nes, NlaEvalSnapshot *snapshot)
-{
-       NlaStrip *strip = nes->strip;
-
-       /* to prevent potential infinite recursion problems (i.e. transition strip, beside meta strip containing a transition
-        * several levels deep inside it), we tag the current strip as being evaluated, and clear this when we leave
-        */
-       /* TODO: be careful with this flag, since some edit tools may be running and have set this while animplayback was running */
-       if (strip->flag & NLASTRIP_FLAG_EDIT_TOUCHED)
-               return;
-       strip->flag |= NLASTRIP_FLAG_EDIT_TOUCHED;
-
-       /* actions to take depend on the type of strip */
-       switch (strip->type) {
-               case NLASTRIP_TYPE_CLIP: /* action-clip */
-                       nlastrip_evaluate_actionclip(ptr, channels, modifiers, nes, snapshot);
-                       break;
-               case NLASTRIP_TYPE_TRANSITION: /* transition */
-                       nlastrip_evaluate_transition(depsgraph, ptr, channels, modifiers, nes, snapshot);
-                       break;
-               case NLASTRIP_TYPE_META: /* meta */
-                       nlastrip_evaluate_meta(depsgraph, ptr, channels, modifiers, nes, snapshot);
-                       break;
-
-               default: /* do nothing */
-                       break;
-       }
-
-       /* clear temp recursion safe-check */
-       strip->flag &= ~NLASTRIP_FLAG_EDIT_TOUCHED;
+void nlastrip_evaluate(Depsgraph *depsgraph,
+                       PointerRNA *ptr,
+                       NlaEvalData *channels,
+                       ListBase *modifiers,
+                       NlaEvalStrip *nes,
+                       NlaEvalSnapshot *snapshot)
+{
+  NlaStrip *strip = nes->strip;
+
+  /* to prevent potential infinite recursion problems (i.e. transition strip, beside meta strip containing a transition
+   * several levels deep inside it), we tag the current strip as being evaluated, and clear this when we leave
+   */
+  /* TODO: be careful with this flag, since some edit tools may be running and have set this while animplayback was running */
+  if (strip->flag & NLASTRIP_FLAG_EDIT_TOUCHED) {
+    return;
+  }
+  strip->flag |= NLASTRIP_FLAG_EDIT_TOUCHED;
+
+  /* actions to take depend on the type of strip */
+  switch (strip->type) {
+    case NLASTRIP_TYPE_CLIP: /* action-clip */
+      nlastrip_evaluate_actionclip(ptr, channels, modifiers, nes, snapshot);
+      break;
+    case NLASTRIP_TYPE_TRANSITION: /* transition */
+      nlastrip_evaluate_transition(depsgraph, ptr, channels, modifiers, nes, snapshot);
+      break;
+    case NLASTRIP_TYPE_META: /* meta */
+      nlastrip_evaluate_meta(depsgraph, ptr, channels, modifiers, nes, snapshot);
+      break;
+
+    default: /* do nothing */
+      break;
+  }
+
+  /* clear temp recursion safe-check */
+  strip->flag &= ~NLASTRIP_FLAG_EDIT_TOUCHED;
 }
 
 /* write the accumulated settings to */
-void nladata_flush_channels(Depsgraph *depsgraph, PointerRNA *ptr, NlaEvalData *channels, NlaEvalSnapshot *snapshot)
-{
-       /* sanity checks */
-       if (channels == NULL)
-               return;
-
-       const bool is_active_depsgraph = DEG_is_active(depsgraph);
-
-       /* for each channel with accumulated values, write its value on the property it affects */
-       for (NlaEvalChannel *nec = channels->channels.first; nec; nec = nec->next) {
-               NlaEvalChannelSnapshot *nec_snapshot = nlaeval_snapshot_find_channel(snapshot, nec);
-
-               PathResolvedRNA rna = { nec->key.ptr, nec->key.prop, -1 };
-
-               for (int i = 0; i < nec_snapshot->length; i++) {
-                       if (BLI_BITMAP_TEST(nec->valid.ptr, i)) {
-                               float value = nec_snapshot->values[i];
-                               if (nec->is_array) {
-                                       rna.prop_index = i;
-                               }
-                               animsys_write_rna_setting(&rna, value);
-                               if (is_active_depsgraph) {
-                                       animsys_write_orig_anim_rna(ptr, nec->rna_path, rna.prop_index, value);
-                               }
-                       }
-               }
-       }
+void nladata_flush_channels(Depsgraph *depsgraph,
+                            PointerRNA *ptr,
+                            NlaEvalData *channels,
+                            NlaEvalSnapshot *snapshot)
+{
+  /* sanity checks */
+  if (channels == NULL) {
+    return;
+  }
+
+  const bool is_active_depsgraph = DEG_is_active(depsgraph);
+
+  /* for each channel with accumulated values, write its value on the property it affects */
+  for (NlaEvalChannel *nec = channels->channels.first; nec; nec = nec->next) {
+    NlaEvalChannelSnapshot *nec_snapshot = nlaeval_snapshot_find_channel(snapshot, nec);
+
+    PathResolvedRNA rna = {nec->key.ptr, nec->key.prop, -1};
+
+    for (int i = 0; i < nec_snapshot->length; i++) {
+      if (BLI_BITMAP_TEST(nec->valid.ptr, i)) {
+        float value = nec_snapshot->values[i];
+        if (nec->is_array) {
+          rna.prop_index = i;
+        }
+        animsys_write_rna_setting(&rna, value);
+        if (is_active_depsgraph) {
+          animsys_write_orig_anim_rna(ptr, nec->rna_path, rna.prop_index, value);
+        }
+      }
+    }
+  }
 }
 
 /* ---------------------- */
 
-static void nla_eval_domain_action(PointerRNA *ptr, NlaEvalData *channels, bAction *act, GSet *touched_actions)
+static void nla_eval_domain_action(PointerRNA *ptr,
+                                   NlaEvalData *channels,
+                                   bAction *act,
+                                   GSet *touched_actions)
 {
-       if (!BLI_gset_add(touched_actions, act)) {
-               return;
-       }
+  if (!BLI_gset_add(touched_actions, act)) {
+    return;
+  }
 
-       for (FCurve *fcu = act->curves.first; fcu; fcu = fcu->next) {
-               /* check if this curve should be skipped */
-               if (fcu->flag & (FCURVE_MUTED | FCURVE_DISABLED))
-                       continue;
-               if ((fcu->grp) && (fcu->grp->flag & AGRP_MUTED))
-                       continue;
+  for (FCurve *fcu = act->curves.first; fcu; fcu = fcu->next) {
+    /* check if this curve should be skipped */
+    if (fcu->flag & (FCURVE_MUTED | FCURVE_DISABLED)) {
+      continue;
+    }
+    if ((fcu->grp) && (fcu->grp->flag & AGRP_MUTED)) {
+      continue;
+    }
 
-               NlaEvalChannel *nec = nlaevalchan_verify(ptr, channels, fcu->rna_path);
+    NlaEvalChannel *nec = nlaevalchan_verify(ptr, channels, fcu->rna_path);
 
-               if (nec != NULL) {
-                       /* For quaternion properties, enable all sub-channels. */
-                       if (nec->mix_mode == NEC_MIX_QUATERNION) {
-                               BLI_bitmap_set_all(nec->valid.ptr, true, 4);
-                               continue;
-                       }
+    if (nec != NULL) {
+      /* For quaternion properties, enable all sub-channels. */
+      if (nec->mix_mode == NEC_MIX_QUATERNION) {
+        BLI_bitmap_set_all(nec->valid.ptr, true, 4);
+        continue;
+      }
 
-                       int idx = nlaevalchan_validate_index(nec, fcu->array_index);
+      int idx = nlaevalchan_validate_index(nec, fcu->array_index);
 
-                       if (idx >= 0) {
-                               BLI_BITMAP_ENABLE(nec->valid.ptr, idx);
-                       }
-               }
-       }
+      if (idx >= 0) {
+        BLI_BITMAP_ENABLE(nec->valid.ptr, idx);
+      }
+    }
+  }
 }
 
-static void nla_eval_domain_strips(PointerRNA *ptr, NlaEvalData *channels, ListBase *strips, GSet *touched_actions)
+static void nla_eval_domain_strips(PointerRNA *ptr,
+                                   NlaEvalData *channels,
+                                   ListBase *strips,
+                                   GSet *touched_actions)
 {
-       for (NlaStrip *strip = strips->first; strip; strip = strip->next) {
-               /* check strip's action */
-               if (strip->act) {
-                       nla_eval_domain_action(ptr, channels, strip->act, touched_actions);
-               }
+  for (NlaStrip *strip = strips->first; strip; strip = strip->next) {
+    /* check strip's action */
+    if (strip->act) {
+      nla_eval_domain_action(ptr, channels, strip->act, touched_actions);
+    }
 
-               /* check sub-strips (if metas) */
-               nla_eval_domain_strips(ptr, channels, &strip->strips, touched_actions);
-       }
+    /* check sub-strips (if metas) */
+    nla_eval_domain_strips(ptr, channels, &strip->strips, touched_actions);
+  }
 }
 
 /**
@@ -3088,31 +3331,33 @@ static void nla_eval_domain_strips(PointerRNA *ptr, NlaEvalData *channels, ListB
  */
 static void animsys_evaluate_nla_domain(PointerRNA *ptr, NlaEvalData *channels, AnimData *adt)
 {
-       GSet *touched_actions = BLI_gset_ptr_new(__func__);
+  GSet *touched_actions = BLI_gset_ptr_new(__func__);
 
-       if (adt->action) {
-               nla_eval_domain_action(ptr, channels, adt->action, touched_actions);
-       }
+  if (adt->action) {
+    nla_eval_domain_action(ptr, channels, adt->action, touched_actions);
+  }
 
-       /* NLA Data - Animation Data for Strips */
-       for (NlaTrack *nlt = adt->nla_tracks.first; nlt; nlt = nlt->next) {
-               /* solo and muting are mutually exclusive... */
-               if (adt->flag & ADT_NLA_SOLO_TRACK) {
-                       /* skip if there is a solo track, but this isn't it */
-                       if ((nlt->flag & NLATRACK_SOLO) == 0)
-                               continue;
-                       /* else - mute doesn't matter */
-               }
-               else {
-                       /* no solo tracks - skip track if muted */
-                       if (nlt->flag & NLATRACK_MUTED)
-                               continue;
-               }
+  /* NLA Data - Animation Data for Strips */
+  for (NlaTrack *nlt = adt->nla_tracks.first; nlt; nlt = nlt->next) {
+    /* solo and muting are mutually exclusive... */
+    if (adt->flag & ADT_NLA_SOLO_TRACK) {
+      /* skip if there is a solo track, but this isn't it */
+      if ((nlt->flag & NLATRACK_SOLO) == 0) {
+        continue;
+      }
+      /* else - mute doesn't matter */
+    }
+    else {
+      /* no solo tracks - skip track if muted */
+      if (nlt->flag & NLATRACK_MUTED) {
+        continue;
+      }
+    }
 
-               nla_eval_domain_strips(ptr, channels, &nlt->strips, touched_actions);
-       }
+    nla_eval_domain_strips(ptr, channels, &nlt->strips, touched_actions);
+  }
 
-       BLI_gset_free(touched_actions, NULL);
+  BLI_gset_free(touched_actions, NULL);
 }
 
 /* ---------------------- */
@@ -3124,169 +3369,193 @@ static void animsys_evaluate_nla_domain(PointerRNA *ptr, NlaEvalData *channels,
  * \param[out] r_context If not NULL, data about the currently edited strip is stored here and excluded from value calculation.
  * \return false if NLA evaluation isn't actually applicable
  */
-static bool animsys_evaluate_nla(Depsgraph *depsgraph, NlaEvalData *echannels, PointerRNA *ptr, AnimData *adt, float ctime, NlaKeyframingContext *r_context)
-{
-       NlaTrack *nlt;
-       short track_index = 0;
-       bool has_strips = false;
-
-       ListBase estrips = {NULL, NULL};
-       NlaEvalStrip *nes;
-       NlaStrip dummy_strip_buf;
-
-       /* dummy strip for active action */
-       NlaStrip *dummy_strip = r_context ? &r_context->strip : &dummy_strip_buf;
-
-       memset(dummy_strip, 0, sizeof(*dummy_strip));
-
-       /* 1. get the stack of strips to evaluate at current time (influence calculated here) */
-       for (nlt = adt->nla_tracks.first; nlt; nlt = nlt->next, track_index++) {
-               /* stop here if tweaking is on and this strip is the tweaking track (it will be the first one that's 'disabled')... */
-               if ((adt->flag & ADT_NLA_EDIT_ON) && (nlt->flag & NLATRACK_DISABLED))
-                       break;
-
-               /* solo and muting are mutually exclusive... */
-               if (adt->flag & ADT_NLA_SOLO_TRACK) {
-                       /* skip if there is a solo track, but this isn't it */
-                       if ((nlt->flag & NLATRACK_SOLO) == 0)
-                               continue;
-                       /* else - mute doesn't matter */
-               }
-               else {
-                       /* no solo tracks - skip track if muted */
-                       if (nlt->flag & NLATRACK_MUTED)
-                               continue;
-               }
-
-               /* if this track has strips (but maybe they won't be suitable), set has_strips
-                * - used for mainly for still allowing normal action evaluation...
-                */
-               if (nlt->strips.first)
-                       has_strips = true;
-
-               /* otherwise, get strip to evaluate for this channel */
-               nes = nlastrips_ctime_get_strip(depsgraph, &estrips, &nlt->strips, track_index, ctime);
-               if (nes) nes->track = nlt;
-       }
-
-       /* add 'active' Action (may be tweaking track) as last strip to evaluate in NLA stack
-        * - only do this if we're not exclusively evaluating the 'solo' NLA-track
-        * - however, if the 'solo' track houses the current 'tweaking' strip,
-        *   then we should allow this to play, otherwise nothing happens
-        */
-       if ((adt->action) && ((adt->flag & ADT_NLA_SOLO_TRACK) == 0 || (adt->flag & ADT_NLA_EDIT_ON))) {
-               /* if there are strips, evaluate action as per NLA rules */
-               if ((has_strips) || (adt->actstrip)) {
-                       /* make dummy NLA strip, and add that to the stack */
-                       ListBase dummy_trackslist;
-
-                       dummy_trackslist.first = dummy_trackslist.last = dummy_strip;
-
-                       /* Strips with a user-defined time curve don't get properly remapped for editing
-                        * at the moment, so mapping them just for display may be confusing. */
-                       bool is_inplace_tweak = (nlt) && !(adt->flag & ADT_NLA_EDIT_NOMAP) && !(adt->actstrip->flag & NLASTRIP_FLAG_USR_TIME);
-
-                       if (is_inplace_tweak) {
-                               /* edit active action in-place according to its active strip, so copy the data  */
-                               memcpy(dummy_strip, adt->actstrip, sizeof(NlaStrip));
-                               dummy_strip->next = dummy_strip->prev = NULL;
-                       }
-                       else {
-                               /* set settings of dummy NLA strip from AnimData settings */
-                               dummy_strip->act = adt->action;
-
-                               /* action range is calculated taking F-Modifiers into account (which making new strips doesn't do due to the troublesome nature of that) */
-                               calc_action_range(dummy_strip->act, &dummy_strip->actstart, &dummy_strip->actend, 1);
-                               dummy_strip->start = dummy_strip->actstart;
-                               dummy_strip->end = (IS_EQF(dummy_strip->actstart, dummy_strip->actend)) ?  (dummy_strip->actstart + 1.0f) : (dummy_strip->actend);
-
-                               /* Always use the blend mode of the strip in tweak mode, even if not in-place. */
-                               if (nlt && adt->actstrip) {
-                                       dummy_strip->blendmode = adt->actstrip->blendmode;
-                                       dummy_strip->extendmode = NLASTRIP_EXTEND_HOLD;
-                               }
-                               else {
-                                       dummy_strip->blendmode = adt->act_blendmode;
-                                       dummy_strip->extendmode = adt->act_extendmode;
-                               }
-
-                               /* Unless extendmode is Nothing (might be useful for flattening NLA evaluation), disable range. */
-                               if (dummy_strip->extendmode != NLASTRIP_EXTEND_NOTHING) {
-                                       dummy_strip->flag |= NLASTRIP_FLAG_NO_TIME_MAP;
-                               }
-
-                               dummy_strip->influence = adt->act_influence;
-
-                               /* NOTE: must set this, or else the default setting overrides, and this setting doesn't work */
-                               dummy_strip->flag |= NLASTRIP_FLAG_USR_INFLUENCE;
-                       }
-
-                       /* add this to our list of evaluation strips */
-                       if (r_context == NULL) {
-                               nlastrips_ctime_get_strip(depsgraph, &estrips, &dummy_trackslist, -1, ctime);
-                       }
-                       /* If computing the context for keyframing, store data there instead of the list. */
-                       else {
-                               /* The extend mode here effectively controls whether it is possible to keyframe beyond the ends. */
-                               dummy_strip->extendmode = is_inplace_tweak ? NLASTRIP_EXTEND_NOTHING : NLASTRIP_EXTEND_HOLD;
-
-                               r_context->eval_strip = nes = nlastrips_ctime_get_strip(depsgraph, NULL, &dummy_trackslist, -1, ctime);
-
-                               /* These setting combinations require no data from strips below, so exit immediately. */
-                               if ((nes == NULL) || (dummy_strip->blendmode == NLASTRIP_MODE_REPLACE && dummy_strip->influence == 1.0f)) {
-                                       BLI_freelistN(&estrips);
-                                       return true;
-                               }
-                       }
-               }
-               else {
-                       /* special case - evaluate as if there isn't any NLA data */
-                       BLI_freelistN(&estrips);
-                       return false;
-               }
-       }
-
-       /* only continue if there are strips to evaluate */
-       if (BLI_listbase_is_empty(&estrips))
-               return true;
-
-       /* 2. for each strip, evaluate then accumulate on top of existing channels, but don't set values yet */
-       for (nes = estrips.first; nes; nes = nes->next)
-               nlastrip_evaluate(depsgraph, ptr, echannels, NULL, nes, &echannels->eval_snapshot);
-
-       /* 3. free temporary evaluation data that's not used elsewhere */
-       BLI_freelistN(&estrips);
-       return true;
+static bool animsys_evaluate_nla(Depsgraph *depsgraph,
+                                 NlaEvalData *echannels,
+                                 PointerRNA *ptr,
+                                 AnimData *adt,
+                                 float ctime,
+                                 NlaKeyframingContext *r_context)
+{
+  NlaTrack *nlt;
+  short track_index = 0;
+  bool has_strips = false;
+
+  ListBase estrips = {NULL, NULL};
+  NlaEvalStrip *nes;
+  NlaStrip dummy_strip_buf;
+
+  /* dummy strip for active action */
+  NlaStrip *dummy_strip = r_context ? &r_context->strip : &dummy_strip_buf;
+
+  memset(dummy_strip, 0, sizeof(*dummy_strip));
+
+  /* 1. get the stack of strips to evaluate at current time (influence calculated here) */
+  for (nlt = adt->nla_tracks.first; nlt; nlt = nlt->next, track_index++) {
+    /* stop here if tweaking is on and this strip is the tweaking track (it will be the first one that's 'disabled')... */
+    if ((adt->flag & ADT_NLA_EDIT_ON) && (nlt->flag & NLATRACK_DISABLED)) {
+      break;
+    }
+
+    /* solo and muting are mutually exclusive... */
+    if (adt->flag & ADT_NLA_SOLO_TRACK) {
+      /* skip if there is a solo track, but this isn't it */
+      if ((nlt->flag & NLATRACK_SOLO) == 0) {
+        continue;
+      }
+      /* else - mute doesn't matter */
+    }
+    else {
+      /* no solo tracks - skip track if muted */
+      if (nlt->flag & NLATRACK_MUTED) {
+        continue;
+      }
+    }
+
+    /* if this track has strips (but maybe they won't be suitable), set has_strips
+     * - used for mainly for still allowing normal action evaluation...
+     */
+    if (nlt->strips.first) {
+      has_strips = true;
+    }
+
+    /* otherwise, get strip to evaluate for this channel */
+    nes = nlastrips_ctime_get_strip(depsgraph, &estrips, &nlt->strips, track_index, ctime);
+    if (nes) {
+      nes->track = nlt;
+    }
+  }
+
+  /* add 'active' Action (may be tweaking track) as last strip to evaluate in NLA stack
+   * - only do this if we're not exclusively evaluating the 'solo' NLA-track
+   * - however, if the 'solo' track houses the current 'tweaking' strip,
+   *   then we should allow this to play, otherwise nothing happens
+   */
+  if ((adt->action) && ((adt->flag & ADT_NLA_SOLO_TRACK) == 0 || (adt->flag & ADT_NLA_EDIT_ON))) {
+    /* if there are strips, evaluate action as per NLA rules */
+    if ((has_strips) || (adt->actstrip)) {
+      /* make dummy NLA strip, and add that to the stack */
+      ListBase dummy_trackslist;
+
+      dummy_trackslist.first = dummy_trackslist.last = dummy_strip;
+
+      /* Strips with a user-defined time curve don't get properly remapped for editing
+       * at the moment, so mapping them just for display may be confusing. */
+      bool is_inplace_tweak = (nlt) && !(adt->flag & ADT_NLA_EDIT_NOMAP) &&
+                              !(adt->actstrip->flag & NLASTRIP_FLAG_USR_TIME);
+
+      if (is_inplace_tweak) {
+        /* edit active action in-place according to its active strip, so copy the data  */
+        memcpy(dummy_strip, adt->actstrip, sizeof(NlaStrip));
+        dummy_strip->next = dummy_strip->prev = NULL;
+      }
+      else {
+        /* set settings of dummy NLA strip from AnimData settings */
+        dummy_strip->act = adt->action;
+
+        /* action range is calculated taking F-Modifiers into account (which making new strips doesn't do due to the troublesome nature of that) */
+        calc_action_range(dummy_strip->act, &dummy_strip->actstart, &dummy_strip->actend, 1);
+        dummy_strip->start = dummy_strip->actstart;
+        dummy_strip->end = (IS_EQF(dummy_strip->actstart, dummy_strip->actend)) ?
+                               (dummy_strip->actstart + 1.0f) :
+                               (dummy_strip->actend);
+
+        /* Always use the blend mode of the strip in tweak mode, even if not in-place. */
+        if (nlt && adt->actstrip) {
+          dummy_strip->blendmode = adt->actstrip->blendmode;
+          dummy_strip->extendmode = NLASTRIP_EXTEND_HOLD;
+        }
+        else {
+          dummy_strip->blendmode = adt->act_blendmode;
+          dummy_strip->extendmode = adt->act_extendmode;
+        }
+
+        /* Unless extendmode is Nothing (might be useful for flattening NLA evaluation), disable range. */
+        if (dummy_strip->extendmode != NLASTRIP_EXTEND_NOTHING) {
+          dummy_strip->flag |= NLASTRIP_FLAG_NO_TIME_MAP;
+        }
+
+        dummy_strip->influence = adt->act_influence;
+
+        /* NOTE: must set this, or else the default setting overrides, and this setting doesn't work */
+        dummy_strip->flag |= NLASTRIP_FLAG_USR_INFLUENCE;
+      }
+
+      /* add this to our list of evaluation strips */
+      if (r_context == NULL) {
+        nlastrips_ctime_get_strip(depsgraph, &estrips, &dummy_trackslist, -1, ctime);
+      }
+      /* If computing the context for keyframing, store data there instead of the list. */
+      else {
+        /* The extend mode here effectively controls whether it is possible to keyframe beyond the ends. */
+        dummy_strip->extendmode = is_inplace_tweak ? NLASTRIP_EXTEND_NOTHING :
+                                                     NLASTRIP_EXTEND_HOLD;
+
+        r_context->eval_strip = nes = nlastrips_ctime_get_strip(
+            depsgraph, NULL, &dummy_trackslist, -1, ctime);
+
+        /* These setting combinations require no data from strips below, so exit immediately. */
+        if ((nes == NULL) ||
+            (dummy_strip->blendmode == NLASTRIP_MODE_REPLACE && dummy_strip->influence == 1.0f)) {
+          BLI_freelistN(&estrips);
+          return true;
+        }
+      }
+    }
+    else {
+      /* special case - evaluate as if there isn't any NLA data */
+      BLI_freelistN(&estrips);
+      return false;
+    }
+  }
+
+  /* only continue if there are strips to evaluate */
+  if (BLI_listbase_is_empty(&estrips)) {
+    return true;
+  }
+
+  /* 2. for each strip, evaluate then accumulate on top of existing channels, but don't set values yet */
+  for (nes = estrips.first; nes; nes = nes->next) {
+    nlastrip_evaluate(depsgraph, ptr, echannels, NULL, nes, &echannels->eval_snapshot);
+  }
+
+  /* 3. free temporary evaluation data that's not used elsewhere */
+  BLI_freelistN(&estrips);
+  return true;
 }
 
 /* NLA Evaluation function (mostly for use through do_animdata)
  * - All channels that will be affected are not cleared anymore. Instead, we just evaluate into
  *   some temp channels, where values can be accumulated in one go.
  */
-static void animsys_calculate_nla(Depsgraph *depsgraph, PointerRNA *ptr, AnimData *adt, float ctime)
+static void animsys_calculate_nla(Depsgraph *depsgraph,
+                                  PointerRNA *ptr,
+                                  AnimData *adt,
+                                  float ctime)
 {
-       NlaEvalData echannels;
+  NlaEvalData echannels;
 
-       nlaeval_init(&echannels);
+  nlaeval_init(&echannels);
 
-       /* evaluate the NLA stack, obtaining a set of values to flush */
-       if (animsys_evaluate_nla(depsgraph, &echannels, ptr, adt, ctime, NULL)) {
-               /* reset any channels touched by currently inactive actions to default value */
-               animsys_evaluate_nla_domain(ptr, &echannels, adt);
+  /* evaluate the NLA stack, obtaining a set of values to flush */
+  if (animsys_evaluate_nla(depsgraph, &echannels, ptr, adt, ctime, NULL)) {
+    /* reset any channels touched by currently inactive actions to default value */
+    animsys_evaluate_nla_domain(ptr, &echannels, adt);
 
-               /* flush effects of accumulating channels in NLA to the actual data they affect */
-               nladata_flush_channels(depsgraph, ptr, &echannels, &echannels.eval_snapshot);
-       }
-       else {
-               /* special case - evaluate as if there isn't any NLA data */
-               /* TODO: this is really just a stop-gap measure... */
-               if (G.debug & G_DEBUG) CLOG_WARN(&LOG, "NLA Eval: Stopgap for active action on NLA Stack - no strips case");
+    /* flush effects of accumulating channels in NLA to the actual data they affect */
+    nladata_flush_channels(depsgraph, ptr, &echannels, &echannels.eval_snapshot);
+  }
+  else {
+    /* special case - evaluate as if there isn't any NLA data */
+    /* TODO: this is really just a stop-gap measure... */
+    if (G.debug & G_DEBUG) {
+      CLOG_WARN(&LOG, "NLA Eval: Stopgap for active action on NLA Stack - no strips case");
+    }
 
-               animsys_evaluate_action(depsgraph, ptr, adt->action, ctime);
-       }
+    animsys_evaluate_action(depsgraph, ptr, adt->action, ctime);
+  }
 
-       /* free temp data */
-       nlaeval_free(&echannels);
+  /* free temp data */
+  nlaeval_free(&echannels);
 }
 
 /* ---------------------- */
@@ -3299,35 +3568,40 @@ static void animsys_calculate_nla(Depsgraph *depsgraph, PointerRNA *ptr, AnimDat
  * @param ptr RNA pointer to the Object with the animation.
  * @return Keyframing context, or NULL if not necessary.
  */
-NlaKeyframingContext *BKE_animsys_get_nla_keyframing_context(
-        struct ListBase *cache, struct Depsgraph *depsgraph, struct PointerRNA *ptr, struct AnimData *adt, float ctime)
+NlaKeyframingContext *BKE_animsys_get_nla_keyframing_context(struct ListBase *cache,
+                                                             struct Depsgraph *depsgraph,
+                                                             struct PointerRNA *ptr,
+                                                             struct AnimData *adt,
+                                                             float ctime)
 {
-       /* No remapping needed if NLA is off or no action. */
-       if ((adt == NULL) || (adt->action == NULL) || (adt->nla_tracks.first == NULL) || (adt->flag & ADT_NLA_EVAL_OFF)) {
-               return NULL;
-       }
+  /* No remapping needed if NLA is off or no action. */
+  if ((adt == NULL) || (adt->action == NULL) || (adt->nla_tracks.first == NULL) ||
+      (adt->flag & ADT_NLA_EVAL_OFF)) {
+    return NULL;
+  }
 
-       /* No remapping if editing an ordinary Replace action with full influence. */
-       if (!(adt->flag & ADT_NLA_EDIT_ON) && (adt->act_blendmode == NLASTRIP_MODE_REPLACE && adt->act_influence == 1.0f)) {
-               return NULL;
-       }
+  /* No remapping if editing an ordinary Replace action with full influence. */
+  if (!(adt->flag & ADT_NLA_EDIT_ON) &&
+      (adt->act_blendmode == NLASTRIP_MODE_REPLACE && adt->act_influence == 1.0f)) {
+    return NULL;
+  }
 
-       /* Try to find a cached context. */
-       NlaKeyframingContext *ctx = BLI_findptr(cache, adt, offsetof(NlaKeyframingContext, adt));
+  /* Try to find a cached context. */
+  NlaKeyframingContext *ctx = BLI_findptr(cache, adt, offsetof(NlaKeyframingContext, adt));
 
-       if (ctx == NULL) {
-               /* Allocate and evaluate a new context. */
-               ctx = MEM_callocN(sizeof(*ctx), "NlaKeyframingContext");
-               ctx->adt = adt;
+  if (ctx == NULL) {
+    /* Allocate and evaluate a new context. */
+    ctx = MEM_callocN(sizeof(*ctx), "NlaKeyframingContext");
+    ctx->adt = adt;
 
-               nlaeval_init(&ctx->nla_channels);
-               animsys_evaluate_nla(depsgraph, &ctx->nla_channels, ptr, adt, ctime, ctx);
+    nlaeval_init(&ctx->nla_channels);
+    animsys_evaluate_nla(depsgraph, &ctx->nla_channels, ptr, adt, ctime, ctx);
 
-               BLI_assert(ELEM(ctx->strip.act, NULL, adt->action));
-               BLI_addtail(cache, ctx);
-       }
+    BLI_assert(ELEM(ctx->strip.act, NULL, adt->action));
+    BLI_addtail(cache, ctx);
+  }
 
-       return ctx;
+  return ctx;
 }
 
 /**
@@ -3341,84 +3615,99 @@ NlaKeyframingContext *BKE_animsys_get_nla_keyframing_context(
  * @param[out] r_force_all Set to true if all channels must be inserted. May be NULL.
  * @return False if correction fails due to a division by zero, or null r_force_all when all channels are required.
  */
-bool BKE_animsys_nla_remap_keyframe_values(struct NlaKeyframingContext *context, struct PointerRNA *prop_ptr, struct PropertyRNA *prop, float *values, int count, int index, bool *r_force_all)
-{
-       if (r_force_all != NULL) {
-               *r_force_all = false;
-       }
-
-       /* No context means no correction. */
-       if (context == NULL || context->strip.act == NULL) {
-               return true;
-       }
-
-       /* If the strip is not evaluated, it is the same as zero influence. */
-       if (context->eval_strip == NULL) {
-               return false;
-       }
-
-       /* Full influence Replace strips also require no correction. */
-       int blend_mode = context->strip.blendmode;
-       float influence = context->strip.influence;
-
-       if (blend_mode == NLASTRIP_MODE_REPLACE && influence == 1.0f) {
-               return true;
-       }
-
-       /* Zero influence is division by zero. */
-       if (influence <= 0.0f) {
-               return false;
-       }
-
-       /* Find the evaluation channel for the NLA stack below current strip. */
-       NlaEvalChannelKey key = { .ptr = *prop_ptr, .prop = prop, };
-       NlaEvalData *nlaeval = &context->nla_channels;
-       NlaEvalChannel *nec = nlaevalchan_verify_key(nlaeval, NULL, &key);
-
-       if (nec->base_snapshot.length != count) {
-               BLI_assert(!"invalid value count");
-               return false;
-       }
-
-       /* Invert the blending operation to compute the desired key values. */
-       NlaEvalChannelSnapshot *nec_snapshot = nlaeval_snapshot_find_channel(&nlaeval->eval_snapshot, nec);
-
-       float *old_values = nec_snapshot->values;
-
-       if (blend_mode == NLASTRIP_MODE_COMBINE) {
-               /* Quaternion combine handles all sub-channels as a unit. */
-               if (nec->mix_mode == NEC_MIX_QUATERNION) {
-                       if (r_force_all == NULL) {
-                               return false;
-                       }
-
-                       *r_force_all = true;
-
-                       nla_invert_combine_quaternion(old_values, values, influence, values);
-               }
-               else {
-                       float *base_values = nec->base_snapshot.values;
-
-                       for (int i = 0; i < count; i++) {
-                               if (ELEM(index, i, -1)) {
-                                       if (!nla_invert_combine_value(nec->mix_mode, base_values[i], old_values[i], values[i], influence, &values[i])) {
-                                               return false;
-                                       }
-                               }
-                       }
-               }
-       }
-       else {
-               for (int i = 0; i < count; i++) {
-                       if (ELEM(index, i, -1)) {
-                               if (!nla_invert_blend_value(blend_mode, old_values[i], values[i], influence, &values[i])) {
-                                       return false;
-                               }
-                       }
-               }
-       }
-
-       return true;
+bool BKE_animsys_nla_remap_keyframe_values(struct NlaKeyframingContext *context,
+                                           struct PointerRNA *prop_ptr,
+                                           struct PropertyRNA *prop,
+                                           float *values,
+                                           int count,
+                                           int index,
+                                           bool *r_force_all)
+{
+  if (r_force_all != NULL) {
+    *r_force_all = false;
+  }
+
+  /* No context means no correction. */
+  if (context == NULL || context->strip.act == NULL) {
+    return true;
+  }
+
+  /* If the strip is not evaluated, it is the same as zero influence. */
+  if (context->eval_strip == NULL) {
+    return false;
+  }
+
+  /* Full influence Replace strips also require no correction. */
+  int blend_mode = context->strip.blendmode;
+  float influence = context->strip.influence;
+
+  if (blend_mode == NLASTRIP_MODE_REPLACE && influence == 1.0f) {
+    return true;
+  }
+
+  /* Zero influence is division by zero. */
+  if (influence <= 0.0f) {
+    return false;
+  }
+
+  /* Find the evaluation channel for the NLA stack below current strip. */
+  NlaEvalChannelKey key = {
+      .ptr = *prop_ptr,
+      .prop = prop,
+  };
+  NlaEvalData *nlaeval = &context->nla_channels;
+  NlaEvalChannel *nec = nlaevalchan_verify_key(nlaeval, NULL, &key);
+
+  if (nec->base_snapshot.length != count) {
+    BLI_assert(!"invalid value count");
+    return false;
+  }
+
+  /* Invert the blending operation to compute the desired key values. */
+  NlaEvalChannelSnapshot *nec_snapshot = nlaeval_snapshot_find_channel(&nlaeval->eval_snapshot,
+                                                                       nec);
+
+  float *old_values = nec_snapshot->values;
+
+  if (blend_mode == NLASTRIP_MODE_COMBINE) {
+    /* Quaternion combine handles all sub-channels as a unit. */
+    if (nec->mix_mode == NEC_MIX_QUATERNION) {
+      if (r_force_all == NULL) {
+        return false;
+      }
+
+      *r_force_all = true;
+
+      nla_invert_combine_quaternion(old_values, values, influence, values);
+    }
+    else {
+      float *base_values = nec->base_snapshot.values;
+
+      for (int i = 0; i < count; i++) {
+        if (ELEM(index, i, -1)) {
+          if (!nla_invert_combine_value(nec->mix_mode,
+                                        base_values[i],
+                                        old_values[i],
+                                        values[i],
+                                        influence,
+                                        &values[i])) {
+            return false;
+          }
+        }
+      }
+    }
+  }
+  else {
+    for (int i = 0; i < count; i++) {
+      if (ELEM(index, i, -1)) {
+        if (!nla_invert_blend_value(blend_mode, old_values[i], values[i], influence, &values[i])) {
+          return false;
+        }
+      }
+    }
+  }
+
+  return true;
 }
 
 /**
@@ -3426,12 +3715,12 @@ bool BKE_animsys_nla_remap_keyframe_values(struct NlaKeyframingContext *context,
  */
 void BKE_animsys_free_nla_keyframing_context_cache(struct ListBase *cache)
 {
-       for (NlaKeyframingContext *ctx = cache->first; ctx; ctx = ctx->next) {
-               MEM_SAFE_FREE(ctx->eval_strip);
-               nlaeval_free(&ctx->nla_channels);
-       }
+  for (NlaKeyframingContext *ctx = cache->first; ctx; ctx = ctx->next) {
+    MEM_SAFE_FREE(ctx->eval_strip);
+    nlaeval_free(&ctx->nla_channels);
+  }
 
-       BLI_freelistN(cache);
+  BLI_freelistN(cache);
 }
 
 /* ***************************************** */
@@ -3440,15 +3729,15 @@ void BKE_animsys_free_nla_keyframing_context_cache(struct ListBase *cache)
 /* Evaluate Overrides */
 static void animsys_evaluate_overrides(PointerRNA *ptr, AnimData *adt)
 {
-       AnimOverride *aor;
+  AnimOverride *aor;
 
-       /* for each override, simply execute... */
-       for (aor = adt->overrides.first; aor; aor = aor->next) {
-               PathResolvedRNA anim_rna;
-               if (animsys_store_rna_setting(ptr, aor->rna_path, aor->array_index, &anim_rna)) {
-                       animsys_write_rna_setting(&anim_rna, aor->value);
-               }
-       }
+  /* for each override, simply execute... */
+  for (aor = adt->overrides.first; aor; aor = aor->next) {
+    PathResolvedRNA anim_rna;
+    if (animsys_store_rna_setting(ptr, aor->rna_path, aor->array_index, &anim_rna)) {
+      animsys_write_rna_setting(&anim_rna, aor->value);
+    }
+  }
 }
 
 /* ***************************************** */
@@ -3491,58 +3780,61 @@ static void animsys_evaluate_overrides(PointerRNA *ptr, AnimData *adt)
  * and that the flags for which parts of the anim-data settings need to be recalculated
  * have been set already by the depsgraph. Now, we use the recalc
  */
-void BKE_animsys_evaluate_animdata(Depsgraph *depsgraph, Scene *scene, ID *id, AnimData *adt, float ctime, short recalc)
-{
-       PointerRNA id_ptr;
-
-       /* sanity checks */
-       if (ELEM(NULL, id, adt))
-               return;
-
-       /* get pointer to ID-block for RNA to use */
-       RNA_id_pointer_create(id, &id_ptr);
-
-       /* recalculate keyframe data:
-        * - NLA before Active Action, as Active Action behaves as 'tweaking track'
-        *   that overrides 'rough' work in NLA
-        */
-       /* TODO: need to double check that this all works correctly */
-       if (recalc & ADT_RECALC_ANIM) {
-               /* evaluate NLA data */
-               if ((adt->nla_tracks.first) && !(adt->flag & ADT_NLA_EVAL_OFF)) {
-                       /* evaluate NLA-stack
-                        * - active action is evaluated as part of the NLA stack as the last item
-                        */
-                       animsys_calculate_nla(depsgraph, &id_ptr, adt, ctime);
-               }
-               /* evaluate Active Action only */
-               else if (adt->action)
-                       animsys_evaluate_action_ex(depsgraph, &id_ptr, adt->action, ctime);
-       }
-
-       /* recalculate drivers
-        * - Drivers need to be evaluated afterwards, as they can either override
-        *   or be layered on top of existing animation data.
-        * - Drivers should be in the appropriate order to be evaluated without problems...
-        */
-       if (recalc & ADT_RECALC_DRIVERS) {
-               animsys_evaluate_drivers(&id_ptr, adt, ctime);
-       }
-
-       /* always execute 'overrides'
-        * - Overrides allow editing, by overwriting the value(s) set from animation-data, with the
-        *   value last set by the user (and not keyframed yet).
-        * - Overrides are cleared upon frame change and/or keyframing
-        * - It is best that we execute this every time, so that no errors are likely to occur.
-        */
-       animsys_evaluate_overrides(&id_ptr, adt);
-
-       /* execute and clear all cached property update functions */
-       if (scene) {
-               Main *bmain = G.main; // xxx - to get passed in!
-               RNA_property_update_cache_flush(bmain, scene);
-               RNA_property_update_cache_free();
-       }
+void BKE_animsys_evaluate_animdata(
+    Depsgraph *depsgraph, Scene *scene, ID *id, AnimData *adt, float ctime, short recalc)
+{
+  PointerRNA id_ptr;
+
+  /* sanity checks */
+  if (ELEM(NULL, id, adt)) {
+    return;
+  }
+
+  /* get pointer to ID-block for RNA to use */
+  RNA_id_pointer_create(id, &id_ptr);
+
+  /* recalculate keyframe data:
+   * - NLA before Active Action, as Active Action behaves as 'tweaking track'
+   *   that overrides 'rough' work in NLA
+   */
+  /* TODO: need to double check that this all works correctly */
+  if (recalc & ADT_RECALC_ANIM) {
+    /* evaluate NLA data */
+    if ((adt->nla_tracks.first) && !(adt->flag & ADT_NLA_EVAL_OFF)) {
+      /* evaluate NLA-stack
+       * - active action is evaluated as part of the NLA stack as the last item
+       */
+      animsys_calculate_nla(depsgraph, &id_ptr, adt, ctime);
+    }
+    /* evaluate Active Action only */
+    else if (adt->action) {
+      animsys_evaluate_action_ex(depsgraph, &id_ptr, adt->action, ctime);
+    }
+  }
+
+  /* recalculate drivers
+   * - Drivers need to be evaluated afterwards, as they can either override
+   *   or be layered on top of existing animation data.
+   * - Drivers should be in the appropriate order to be evaluated without problems...
+   */
+  if (recalc & ADT_RECALC_DRIVERS) {
+    animsys_evaluate_drivers(&id_ptr, adt, ctime);
+  }
+
+  /* always execute 'overrides'
+   * - Overrides allow editing, by overwriting the value(s) set from animation-data, with the
+   *   value last set by the user (and not keyframed yet).
+   * - Overrides are cleared upon frame change and/or keyframing
+   * - It is best that we execute this every time, so that no errors are likely to occur.
+   */
+  animsys_evaluate_overrides(&id_ptr, adt);
+
+  /* execute and clear all cached property update functions */
+  if (scene) {
+    Main *bmain = G.main;  // xxx - to get passed in!
+    RNA_property_update_cache_flush(bmain, scene);
+    RNA_property_update_cache_free();
+  }
 }
 
 /* Evaluation of all ID-blocks with Animation Data blocks - Animation Data Only
@@ -3552,129 +3844,137 @@ void BKE_animsys_evaluate_animdata(Depsgraph *depsgraph, Scene *scene, ID *id, A
  * 'local' (i.e. belonging in the nearest ID-block that setting is related to, not a
  * standard 'root') block are overridden by a larger 'user'
  */
-void BKE_animsys_evaluate_all_animation(Main *main, Depsgraph *depsgraph, Scene *scene, float ctime)
-{
-       ID *id;
-
-       if (G.debug & G_DEBUG)
-               printf("Evaluate all animation - %f\n", ctime);
-
-       /* macros for less typing
-        * - only evaluate animation data for id if it has users (and not just fake ones)
-        * - whether animdata exists is checked for by the evaluation function, though taking
-        *   this outside of the function may make things slightly faster?
-        */
+void BKE_animsys_evaluate_all_animation(Main *main,
+                                        Depsgraph *depsgraph,
+                                        Scene *scene,
+                                        float ctime)
+{
+  ID *id;
+
+  if (G.debug & G_DEBUG) {
+    printf("Evaluate all animation - %f\n", ctime);
+  }
+
+  /* macros for less typing
+     * - only evaluate animation data for id if it has users (and not just fake ones)
+     * - whether animdata exists is checked for by the evaluation function, though taking
+     *   this outside of the function may make things slightly faster?
+     */
 #define EVAL_ANIM_IDS(first, aflag) \
-       for (id = first; id; id = id->next) { \
-               if (ID_REAL_USERS(id) > 0) { \
-                       AnimData *adt = BKE_animdata_from_id(id); \
-                       BKE_animsys_evaluate_animdata(depsgraph, scene, id, adt, ctime, aflag); \
-               } \
-       } (void)0
-
-       /* another macro for the "embedded" nodetree cases
-        * - this is like EVAL_ANIM_IDS, but this handles the case "embedded nodetrees"
-        *   (i.e. scene/material/texture->nodetree) which we need a special exception
-        *   for, otherwise they'd get skipped
-        * - ntp = "node tree parent" = datablock where node tree stuff resides
-        */
+  for (id = first; id; id = id->next) { \
+    if (ID_REAL_USERS(id) > 0) { \
+      AnimData *adt = BKE_animdata_from_id(id); \
+      BKE_animsys_evaluate_animdata(depsgraph, scene, id, adt, ctime, aflag); \
+    } \
+  } \
+  (void)0
+
+  /* another macro for the "embedded" nodetree cases
+     * - this is like EVAL_ANIM_IDS, but this handles the case "embedded nodetrees"
+     *   (i.e. scene/material/texture->nodetree) which we need a special exception
+     *   for, otherwise they'd get skipped
+     * - ntp = "node tree parent" = datablock where node tree stuff resides
+     */
 #define EVAL_ANIM_NODETREE_IDS(first, NtId_Type, aflag) \
-       for (id = first; id; id = id->next) { \
-               if (ID_REAL_USERS(id) > 0) { \
-                       AnimData *adt = BKE_animdata_from_id(id); \
-                       NtId_Type *ntp = (NtId_Type *)id; \
-                       if (ntp->nodetree) { \
-                               AnimData *adt2 = BKE_animdata_from_id((ID *)ntp->nodetree); \
-                               BKE_animsys_evaluate_animdata(depsgraph, scene, (ID *)ntp->nodetree, adt2, ctime, ADT_RECALC_ANIM); \
-                       } \
-                       BKE_animsys_evaluate_animdata(depsgraph, scene, id, adt, ctime, aflag); \
-               } \
-       } (void)0
+  for (id = first; id; id = id->next) { \
+    if (ID_REAL_USERS(id) > 0) { \
+      AnimData *adt = BKE_animdata_from_id(id); \
+      NtId_Type *ntp = (NtId_Type *)id; \
+      if (ntp->nodetree) { \
+        AnimData *adt2 = BKE_animdata_from_id((ID *)ntp->nodetree); \
+        BKE_animsys_evaluate_animdata( \
+            depsgraph, scene, (ID *)ntp->nodetree, adt2, ctime, ADT_RECALC_ANIM); \
+      } \
+      BKE_animsys_evaluate_animdata(depsgraph, scene, id, adt, ctime, aflag); \
+    } \
+  } \
+  (void)0
 
-       /* optimization:
-        * when there are no actions, don't go over database and loop over heaps of datablocks,
-        * which should ultimately be empty, since it is not possible for now to have any animation
-        * without some actions, and drivers wouldn't get affected by any state changes
-        *
-        * however, if there are some curves, we will need to make sure that their 'ctime' property gets
-        * set correctly, so this optimization must be skipped in that case...
-        */
-       if (BLI_listbase_is_empty(&main->action) && BLI_listbase_is_empty(&main->curve)) {
-               if (G.debug & G_DEBUG)
-                       printf("\tNo Actions, so no animation needs to be evaluated...\n");
+  /* optimization:
+   * when there are no actions, don't go over database and loop over heaps of datablocks,
+   * which should ultimately be empty, since it is not possible for now to have any animation
+   * without some actions, and drivers wouldn't get affected by any state changes
+   *
+   * however, if there are some curves, we will need to make sure that their 'ctime' property gets
+   * set correctly, so this optimization must be skipped in that case...
+   */
+  if (BLI_listbase_is_empty(&main->actions) && BLI_listbase_is_empty(&main->curves)) {
+    if (G.debug & G_DEBUG) {
+      printf("\tNo Actions, so no animation needs to be evaluated...\n");
+    }
 
-               return;
-       }
+    return;
+  }
 
-       /* nodes */
-       EVAL_ANIM_IDS(main->nodetree.first, ADT_RECALC_ANIM);
+  /* nodes */
+  EVAL_ANIM_IDS(main->nodetrees.first, ADT_RECALC_ANIM);
 
-       /* textures */
-       EVAL_ANIM_NODETREE_IDS(main->tex.first, Tex, ADT_RECALC_ANIM);
+  /* textures */
+  EVAL_ANIM_NODETREE_IDS(main->textures.first, Tex, ADT_RECALC_ANIM);
 
-       /* lamps */
-       EVAL_ANIM_NODETREE_IDS(main->lamp.first, Lamp, ADT_RECALC_ANIM);
+  /* lights */
+  EVAL_ANIM_NODETREE_IDS(main->lights.first, Light, ADT_RECALC_ANIM);
 
-       /* materials */
-       EVAL_ANIM_NODETREE_IDS(main->mat.first, Material, ADT_RECALC_ANIM);
+  /* materials */
+  EVAL_ANIM_NODETREE_IDS(main->materials.first, Material, ADT_RECALC_ANIM);
 
-       /* cameras */
-       EVAL_ANIM_IDS(main->camera.first, ADT_RECALC_ANIM);
+  /* cameras */
+  EVAL_ANIM_IDS(main->cameras.first, ADT_RECALC_ANIM);
 
-       /* shapekeys */
-       EVAL_ANIM_IDS(main->key.first, ADT_RECALC_ANIM);
+  /* shapekeys */
+  EVAL_ANIM_IDS(main->shapekeys.first, ADT_RECALC_ANIM);
 
-       /* metaballs */
-       EVAL_ANIM_IDS(main->mball.first, ADT_RECALC_ANIM);
+  /* metaballs */
+  EVAL_ANIM_IDS(main->metaballs.first, ADT_RECALC_ANIM);
 
-       /* curves */
-       EVAL_ANIM_IDS(main->curve.first, ADT_RECALC_ANIM);
+  /* curves */
+  EVAL_ANIM_IDS(main->curves.first, ADT_RECALC_ANIM);
 
-       /* armatures */
-       EVAL_ANIM_IDS(main->armature.first, ADT_RECALC_ANIM);
+  /* armatures */
+  EVAL_ANIM_IDS(main->armatures.first, ADT_RECALC_ANIM);
 
-       /* lattices */
-       EVAL_ANIM_IDS(main->latt.first, ADT_RECALC_ANIM);
+  /* lattices */
+  EVAL_ANIM_IDS(main->lattices.first, ADT_RECALC_ANIM);
 
-       /* meshes */
-       EVAL_ANIM_IDS(main->mesh.first, ADT_RECALC_ANIM);
+  /* meshes */
+  EVAL_ANIM_IDS(main->meshes.first, ADT_RECALC_ANIM);
 
-       /* particles */
-       EVAL_ANIM_IDS(main->particle.first, ADT_RECALC_ANIM);
+  /* particles */
+  EVAL_ANIM_IDS(main->particles.first, ADT_RECALC_ANIM);
 
-       /* speakers */
-       EVAL_ANIM_IDS(main->speaker.first, ADT_RECALC_ANIM);
+  /* speakers */
+  EVAL_ANIM_IDS(main->speakers.first, ADT_RECALC_ANIM);
 
-       /* movie clips */
-       EVAL_ANIM_IDS(main->movieclip.first, ADT_RECALC_ANIM);
+  /* movie clips */
+  EVAL_ANIM_IDS(main->movieclips.first, ADT_RECALC_ANIM);
 
-       /* linestyles */
-       EVAL_ANIM_IDS(main->linestyle.first, ADT_RECALC_ANIM);
+  /* linestyles */
+  EVAL_ANIM_IDS(main->linestyles.first, ADT_RECALC_ANIM);
 
-       /* grease pencil */
-       EVAL_ANIM_IDS(main->gpencil.first, ADT_RECALC_ANIM);
+  /* grease pencil */
+  EVAL_ANIM_IDS(main->gpencils.first, ADT_RECALC_ANIM);
 
-       /* palettes */
-       EVAL_ANIM_IDS(main->palettes.first, ADT_RECALC_ANIM);
+  /* palettes */
+  EVAL_ANIM_IDS(main->palettes.first, ADT_RECALC_ANIM);
 
-       /* cache files */
-       EVAL_ANIM_IDS(main->cachefiles.first, ADT_RECALC_ANIM);
+  /* cache files */
+  EVAL_ANIM_IDS(main->cachefiles.first, ADT_RECALC_ANIM);
 
-       /* objects */
-       /* ADT_RECALC_ANIM doesn't need to be supplied here, since object AnimData gets
-        * this tagged by Depsgraph on framechange. This optimization means that objects
-        * linked from other (not-visible) scenes will not need their data calculated.
-        */
-       EVAL_ANIM_IDS(main->object.first, 0);
+  /* objects */
+  /* ADT_RECALC_ANIM doesn't need to be supplied here, since object AnimData gets
+   * this tagged by Depsgraph on framechange. This optimization means that objects
+   * linked from other (not-visible) scenes will not need their data calculated.
+   */
+  EVAL_ANIM_IDS(main->objects.first, 0);
 
-       /* masks */
-       EVAL_ANIM_IDS(main->mask.first, ADT_RECALC_ANIM);
+  /* masks */
+  EVAL_ANIM_IDS(main->masks.first, ADT_RECALC_ANIM);
 
-       /* worlds */
-       EVAL_ANIM_NODETREE_IDS(main->world.first, World, ADT_RECALC_ANIM);
+  /* worlds */
+  EVAL_ANIM_NODETREE_IDS(main->worlds.first, World, ADT_RECALC_ANIM);
 
-       /* scenes */
-       EVAL_ANIM_NODETREE_IDS(main->scene.first, Scene, ADT_RECALC_ANIM);
+  /* scenes */
+  EVAL_ANIM_NODETREE_IDS(main->scenes.first, Scene, ADT_RECALC_ANIM);
 }
 
 /* ***************************************** */
@@ -3684,33 +3984,33 @@ void BKE_animsys_evaluate_all_animation(Main *main, Depsgraph *depsgraph, Scene
 
 void BKE_animsys_eval_animdata(Depsgraph *depsgraph, ID *id)
 {
-       float ctime = DEG_get_ctime(depsgraph);
-       AnimData *adt = BKE_animdata_from_id(id);
-       Scene *scene = NULL; /* XXX: this is only needed for flushing RNA updates,
-                             * which should get handled as part of the dependency graph instead...
-                             */
-       DEG_debug_print_eval_time(depsgraph, __func__, id->name, id, ctime);
-       BKE_animsys_evaluate_animdata(depsgraph, scene, id, adt, ctime, ADT_RECALC_ANIM);
+  float ctime = DEG_get_ctime(depsgraph);
+  AnimData *adt = BKE_animdata_from_id(id);
+  /* XXX: this is only needed for flushing RNA updates,
+   * which should get handled as part of the dependency graph instead. */
+  Scene *scene = NULL;
+  DEG_debug_print_eval_time(depsgraph, __func__, id->name, id, ctime);
+  BKE_animsys_evaluate_animdata(depsgraph, scene, id, adt, ctime, ADT_RECALC_ANIM);
 }
 
 void BKE_animsys_update_driver_array(ID *id)
 {
-       AnimData *adt = BKE_animdata_from_id(id);
+  AnimData *adt = BKE_animdata_from_id(id);
 
-       /* Runtime driver map to avoid O(n^2) lookups in BKE_animsys_eval_driver.
-        * Ideally the depsgraph could pass a pointer to the COW driver directly,
-        * but this is difficult in the current design. */
-       if (adt && adt->drivers.first) {
-               BLI_assert(!adt->driver_array);
+  /* Runtime driver map to avoid O(n^2) lookups in BKE_animsys_eval_driver.
+   * Ideally the depsgraph could pass a pointer to the COW driver directly,
+   * but this is difficult in the current design. */
+  if (adt && adt->drivers.first) {
+    BLI_assert(!adt->driver_array);
 
-               int num_drivers = BLI_listbase_count(&adt->drivers);
-               adt->driver_array = MEM_mallocN(sizeof(FCurve *) * num_drivers, "adt->driver_array");
+    int num_drivers = BLI_listbase_count(&adt->drivers);
+    adt->driver_array = MEM_mallocN(sizeof(FCurve *) * num_drivers, "adt->driver_array");
 
-               int driver_index = 0;
-               for (FCurve *fcu = adt->drivers.first; fcu; fcu = fcu->next) {
-                       adt->driver_array[driver_index++] = fcu;
-               }
-       }
+    int driver_index = 0;
+    for (FCurve *fcu = adt->drivers.first; fcu; fcu = fcu->next) {
+      adt->driver_array[driver_index++] = fcu;
+    }
+  }
 }
 
 void BKE_animsys_eval_driver(Depsgraph *depsgraph,
@@ -3718,74 +4018,71 @@ void BKE_animsys_eval_driver(Depsgraph *depsgraph,
                              int driver_index,
                              ChannelDriver *driver_orig)
 {
-       /* TODO(sergey): De-duplicate with BKE animsys. */
-       PointerRNA id_ptr;
-       bool ok = false;
-
-       /* Lookup driver, accelerated with driver array map. */
-       const AnimData *adt = BKE_animdata_from_id(id);
-       FCurve *fcu;
-
-       if (adt->driver_array) {
-               fcu = adt->driver_array[driver_index];
-       }
-       else {
-               fcu = BLI_findlink(&adt->drivers, driver_index);
-       }
-
-       DEG_debug_print_eval_subdata_index(
-               depsgraph, __func__, id->name, id, "fcu", fcu->rna_path, fcu, fcu->array_index);
-
-       RNA_id_pointer_create(id, &id_ptr);
-
-       /* check if this driver's curve should be skipped */
-       if ((fcu->flag & (FCURVE_MUTED | FCURVE_DISABLED)) == 0) {
-               /* check if driver itself is tagged for recalculation */
-               /* XXX driver recalc flag is not set yet by depsgraph! */
-               if ((driver_orig) && !(driver_orig->flag & DRIVER_FLAG_INVALID)) {
-                       /* evaluate this using values set already in other places
-                        * NOTE: for 'layering' option later on, we should check if we should remove old value before adding
-                        *       new to only be done when drivers only changed */
-                       //printf("\told val = %f\n", fcu->curval);
-
-                       PathResolvedRNA anim_rna;
-                       if (animsys_store_rna_setting(&id_ptr, fcu->rna_path, fcu->array_index, &anim_rna)) {
-                               /* Evaluate driver, and write results to COW-domain destination */
-                               const float ctime = DEG_get_ctime(depsgraph);
-                               const float curval = evaluate_fcurve_driver(&anim_rna, fcu, driver_orig, ctime);
-                               ok = animsys_write_rna_setting(&anim_rna, curval);
-
-                               /* Flush results & status codes to original data for UI (T59984) */
-                               if (ok && DEG_is_active(depsgraph)) {
-                                       animsys_write_orig_anim_rna(&id_ptr, fcu->rna_path, fcu->array_index, curval);
-
-                                       /* curval is displayed in the UI, and flag contains error-status codes */
-                                       driver_orig->curval = fcu->driver->curval;
-                                       driver_orig->flag = fcu->driver->flag;
-
-                                       DriverVar *dvar_orig = driver_orig->variables.first;
-                                       DriverVar *dvar = fcu->driver->variables.first;
-                                       for (;
-                                            dvar_orig && dvar;
-                                            dvar_orig = dvar_orig->next, dvar = dvar->next)
-                                       {
-                                               DriverTarget *dtar_orig = &dvar_orig->targets[0];
-                                               DriverTarget *dtar = &dvar->targets[0];
-                                               for (int i = 0; i < MAX_DRIVER_TARGETS; i++, dtar_orig++, dtar++) {
-                                                       dtar_orig->flag = dtar->flag;
-                                               }
-
-                                               dvar_orig->curval = dvar->curval;
-                                               dvar_orig->flag = dvar->flag;
-                                       }
-                               }
-                       }
-
-                       /* set error-flag if evaluation failed */
-                       if (ok == 0) {
-                               CLOG_ERROR(&LOG, "invalid driver - %s[%d]", fcu->rna_path, fcu->array_index);
-                               driver_orig->flag |= DRIVER_FLAG_INVALID;
-                       }
-               }
-       }
+  /* TODO(sergey): De-duplicate with BKE animsys. */
+  PointerRNA id_ptr;
+  bool ok = false;
+
+  /* Lookup driver, accelerated with driver array map. */
+  const AnimData *adt = BKE_animdata_from_id(id);
+  FCurve *fcu;
+
+  if (adt->driver_array) {
+    fcu = adt->driver_array[driver_index];
+  }
+  else {
+    fcu = BLI_findlink(&adt->drivers, driver_index);
+  }
+
+  DEG_debug_print_eval_subdata_index(
+      depsgraph, __func__, id->name, id, "fcu", fcu->rna_path, fcu, fcu->array_index);
+
+  RNA_id_pointer_create(id, &id_ptr);
+
+  /* check if this driver's curve should be skipped */
+  if ((fcu->flag & (FCURVE_MUTED | FCURVE_DISABLED)) == 0) {
+    /* check if driver itself is tagged for recalculation */
+    /* XXX driver recalc flag is not set yet by depsgraph! */
+    if ((driver_orig) && !(driver_orig->flag & DRIVER_FLAG_INVALID)) {
+      /* evaluate this using values set already in other places
+       * NOTE: for 'layering' option later on, we should check if we should remove old value before adding
+       *       new to only be done when drivers only changed */
+      //printf("\told val = %f\n", fcu->curval);
+
+      PathResolvedRNA anim_rna;
+      if (animsys_store_rna_setting(&id_ptr, fcu->rna_path, fcu->array_index, &anim_rna)) {
+        /* Evaluate driver, and write results to COW-domain destination */
+        const float ctime = DEG_get_ctime(depsgraph);
+        const float curval = evaluate_fcurve_driver(&anim_rna, fcu, driver_orig, ctime);
+        ok = animsys_write_rna_setting(&anim_rna, curval);
+
+        /* Flush results & status codes to original data for UI (T59984) */
+        if (ok && DEG_is_active(depsgraph)) {
+          animsys_write_orig_anim_rna(&id_ptr, fcu->rna_path, fcu->array_index, curval);
+
+          /* curval is displayed in the UI, and flag contains error-status codes */
+          driver_orig->curval = fcu->driver->curval;
+          driver_orig->flag = fcu->driver->flag;
+
+          DriverVar *dvar_orig = driver_orig->variables.first;
+          DriverVar *dvar = fcu->driver->variables.first;
+          for (; dvar_orig && dvar; dvar_orig = dvar_orig->next, dvar = dvar->next) {
+            DriverTarget *dtar_orig = &dvar_orig->targets[0];
+            DriverTarget *dtar = &dvar->targets[0];
+            for (int i = 0; i < MAX_DRIVER_TARGETS; i++, dtar_orig++, dtar++) {
+              dtar_orig->flag = dtar->flag;
+            }
+
+            dvar_orig->curval = dvar->curval;
+            dvar_orig->flag = dvar->flag;
+          }
+        }
+      }
+
+      /* set error-flag if evaluation failed */
+      if (ok == 0) {
+        CLOG_ERROR(&LOG, "invalid driver - %s[%d]", fcu->rna_path, fcu->array_index);
+        driver_orig->flag |= DRIVER_FLAG_INVALID;
+      }
+    }
+  }
 }