Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/source
diff options
context:
space:
mode:
authorCampbell Barton <ideasman42@gmail.com>2019-04-16 08:27:37 +0300
committerCampbell Barton <ideasman42@gmail.com>2019-04-16 08:35:17 +0300
commit2f94b170e4e2f62c069eb2ece1f39bace89338fa (patch)
treec8870cf18fd8ed3659fd32521e66f5f61ee947be /source
parent5498e7f193e2399b8693ef17803f864103307b4b (diff)
Cleanup: move motion paths into editors/animation
Having this in blenkernel caused bad level calls to bf_editors_anim, causing tests that use 'blenkernel' to require almost all libraries. (complicating gtest linking & causing large binaries).
Diffstat (limited to 'source')
-rw-r--r--source/blender/blenkernel/BKE_anim.h8
-rw-r--r--source/blender/blenkernel/CMakeLists.txt2
-rw-r--r--source/blender/blenkernel/intern/anim.c292
-rw-r--r--source/blender/editors/animation/CMakeLists.txt2
-rw-r--r--source/blender/editors/animation/anim_motion_paths.c335
-rw-r--r--source/blender/editors/armature/pose_edit.c1
-rw-r--r--source/blender/editors/include/ED_anim_api.h9
-rw-r--r--source/blender/editors/object/object_edit.c1
-rw-r--r--source/blender/python/intern/CMakeLists.txt1
9 files changed, 349 insertions, 302 deletions
diff --git a/source/blender/blenkernel/BKE_anim.h b/source/blender/blenkernel/BKE_anim.h
index 7670d5a04a0..d5bd729cc4e 100644
--- a/source/blender/blenkernel/BKE_anim.h
+++ b/source/blender/blenkernel/BKE_anim.h
@@ -46,14 +46,6 @@ void animviz_free_motionpath(struct bMotionPath *mpath);
struct bMotionPath *animviz_verify_motionpaths(struct ReportList *reports, struct Scene *scene, struct Object *ob, struct bPoseChannel *pchan);
-void animviz_get_object_motionpaths(struct Object *ob, ListBase *targets);
-void animviz_calc_motionpaths(struct Depsgraph *depsgraph,
- struct Main *bmain,
- struct Scene *scene,
- ListBase *targets,
- bool restore,
- bool current_frame_only);
-
/* ---------------------------------------------------- */
/* Curve Paths */
diff --git a/source/blender/blenkernel/CMakeLists.txt b/source/blender/blenkernel/CMakeLists.txt
index 696d252c81d..33c0d435c69 100644
--- a/source/blender/blenkernel/CMakeLists.txt
+++ b/source/blender/blenkernel/CMakeLists.txt
@@ -355,8 +355,6 @@ set(SRC
)
set(LIB
- bf_editor_animation # FIXME, bad level (compare_ak_cfraPtr)
-
bf_blenfont
bf_blenlib
bf_blenloader
diff --git a/source/blender/blenkernel/intern/anim.c b/source/blender/blenkernel/intern/anim.c
index a4ebfec657c..25a657c4745 100644
--- a/source/blender/blenkernel/intern/anim.c
+++ b/source/blender/blenkernel/intern/anim.c
@@ -57,11 +57,6 @@
static CLG_LogRef LOG = {"bke.anim"};
-// XXX bad level call...
-extern short compare_ak_cfraPtr(void *node, void *data);
-extern void agroup_to_keylist(struct AnimData *adt, struct bActionGroup *agrp, struct DLRBT_Tree *keys, int saction_flag);
-extern void action_to_keylist(struct AnimData *adt, struct bAction *act, struct DLRBT_Tree *keys, int saction_flag);
-
/* --------------------- */
/* forward declarations */
@@ -244,293 +239,6 @@ bMotionPath *animviz_verify_motionpaths(ReportList *reports, Scene *scene, Objec
return mpath;
}
-/* ------------------- */
-
-/* Motion path needing to be baked (mpt) */
-typedef struct MPathTarget {
- struct MPathTarget *next, *prev;
-
- bMotionPath *mpath; /* motion path in question */
-
- DLRBT_Tree keys; /* temp, to know where the keyframes are */
-
- /* Original (Source Objects) */
- Object *ob; /* source object */
- bPoseChannel *pchan; /* source posechannel (if applicable) */
-
- /* "Evaluated" Copies (these come from the background COW copie
- * that provide all the coordinates we want to save off)
- */
- Object *ob_eval; /* evaluated object */
-} MPathTarget;
-
-/* ........ */
-
-/* get list of motion paths to be baked for the given object
- * - assumes the given list is ready to be used
- */
-/* TODO: it would be nice in future to be able to update objects dependent on these bones too? */
-void animviz_get_object_motionpaths(Object *ob, ListBase *targets)
-{
- MPathTarget *mpt;
-
- /* object itself first */
- if ((ob->avs.recalc & ANIMVIZ_RECALC_PATHS) && (ob->mpath)) {
- /* new target for object */
- mpt = MEM_callocN(sizeof(MPathTarget), "MPathTarget Ob");
- BLI_addtail(targets, mpt);
-
- mpt->mpath = ob->mpath;
- mpt->ob = ob;
- }
-
- /* bones */
- if ((ob->pose) && (ob->pose->avs.recalc & ANIMVIZ_RECALC_PATHS)) {
- bArmature *arm = ob->data;
- bPoseChannel *pchan;
-
- for (pchan = ob->pose->chanbase.first; pchan; pchan = pchan->next) {
- if ((pchan->bone) && (arm->layer & pchan->bone->layer) && (pchan->mpath)) {
- /* new target for bone */
- mpt = MEM_callocN(sizeof(MPathTarget), "MPathTarget PoseBone");
- BLI_addtail(targets, mpt);
-
- mpt->mpath = pchan->mpath;
- mpt->ob = ob;
- mpt->pchan = pchan;
- }
- }
- }
-}
-
-/* ........ */
-
-/* update scene for current frame */
-static void motionpaths_calc_update_scene(Main *bmain,
- struct Depsgraph *depsgraph)
-{
- /* Do all updates
- * - if this is too slow, resort to using a more efficient way
- * that doesn't force complete update, but for now, this is the
- * most accurate way!
- *
- * TODO(segey): Bring back partial updates, which became impossible
- * with the new depsgraph due to unsorted nature of bases.
- *
- * TODO(sergey): Use evaluation context dedicated to motion paths.
- */
- BKE_scene_graph_update_for_newframe(depsgraph, bmain);
-}
-
-/* ........ */
-
-/* perform baking for the targets on the current frame */
-static void motionpaths_calc_bake_targets(ListBase *targets, int cframe)
-{
- MPathTarget *mpt;
-
- /* for each target, check if it can be baked on the current frame */
- for (mpt = targets->first; mpt; mpt = mpt->next) {
- bMotionPath *mpath = mpt->mpath;
-
- /* current frame must be within the range the cache works for
- * - is inclusive of the first frame, but not the last otherwise we get buffer overruns
- */
- if ((cframe < mpath->start_frame) || (cframe >= mpath->end_frame)) {
- continue;
- }
-
- /* get the relevant cache vert to write to */
- bMotionPathVert *mpv = mpath->points + (cframe - mpath->start_frame);
-
- Object *ob_eval = mpt->ob_eval;
-
- /* Lookup evaluated pose channel, here because the depsgraph
- * evaluation can change them so they are not cached in mpt. */
- bPoseChannel *pchan_eval = NULL;
- if (mpt->pchan) {
- pchan_eval = BKE_pose_channel_find_name(ob_eval->pose, mpt->pchan->name);
- }
-
- /* pose-channel or object path baking? */
- if (pchan_eval) {
- /* heads or tails */
- if (mpath->flag & MOTIONPATH_FLAG_BHEAD) {
- copy_v3_v3(mpv->co, pchan_eval->pose_head);
- }
- else {
- copy_v3_v3(mpv->co, pchan_eval->pose_tail);
- }
-
- /* result must be in worldspace */
- mul_m4_v3(ob_eval->obmat, mpv->co);
- }
- else {
- /* worldspace object location */
- copy_v3_v3(mpv->co, ob_eval->obmat[3]);
- }
-
- float mframe = (float)(cframe);
-
- /* Tag if it's a keyframe */
- if (BLI_dlrbTree_search_exact(&mpt->keys, compare_ak_cfraPtr, &mframe)) {
- mpv->flag |= MOTIONPATH_VERT_KEY;
- }
- else {
- mpv->flag &= ~MOTIONPATH_VERT_KEY;
- }
-
- /* Incremental update on evaluated object if possible, for fast updating
- * while dragging in transform. */
- bMotionPath *mpath_eval = NULL;
- if (mpt->pchan) {
- mpath_eval = (pchan_eval) ? pchan_eval->mpath : NULL;
- }
- else {
- mpath_eval = ob_eval->mpath;
- }
-
- if (mpath_eval && mpath_eval->length == mpath->length) {
- bMotionPathVert *mpv_eval = mpath_eval->points + (cframe - mpath_eval->start_frame);
- *mpv_eval = *mpv;
-
- GPU_VERTBUF_DISCARD_SAFE(mpath_eval->points_vbo);
- GPU_BATCH_DISCARD_SAFE(mpath_eval->batch_line);
- GPU_BATCH_DISCARD_SAFE(mpath_eval->batch_points);
- }
- }
-}
-
-/* Perform baking of the given object's and/or its bones' transforms to motion paths
- * - scene: current scene
- * - ob: object whose flagged motionpaths should get calculated
- * - recalc: whether we need to
- */
-/* TODO: include reports pointer? */
-void animviz_calc_motionpaths(Depsgraph *depsgraph,
- Main *bmain,
- Scene *scene,
- ListBase *targets,
- bool restore,
- bool current_frame_only)
-{
- /* sanity check */
- if (ELEM(NULL, targets, targets->first))
- return;
-
- /* Compute frame range to bake within.
- * TODO: this method could be improved...
- * 1) max range for standard baking
- * 2) minimum range for recalc baking (i.e. between keyframes, but how?) */
- int sfra = INT_MAX;
- int efra = INT_MIN;
-
- for (MPathTarget *mpt = targets->first; mpt; mpt = mpt->next) {
- /* try to increase area to do (only as much as needed) */
- sfra = MIN2(sfra, mpt->mpath->start_frame);
- efra = MAX2(efra, mpt->mpath->end_frame);
- }
-
- if (efra <= sfra) {
- return;
- }
-
- /* Limit frame range if we are updating just the current frame. */
- /* set frame values */
- int cfra = CFRA;
- if (current_frame_only) {
- if (cfra < sfra || cfra > efra) {
- return;
- }
- sfra = efra = cfra;
- }
-
- /* get copies of objects/bones to get the calculated results from
- * (for copy-on-write evaluation), so that we actually get some results
- */
- // TODO: Create a copy of background depsgraph that only contain these entities, and only evaluates them..
- for (MPathTarget *mpt = targets->first; mpt; mpt = mpt->next) {
- mpt->ob_eval = DEG_get_evaluated_object(depsgraph, mpt->ob);
-
- AnimData *adt = BKE_animdata_from_id(&mpt->ob_eval->id);
-
- /* build list of all keyframes in active action for object or pchan */
- BLI_dlrbTree_init(&mpt->keys);
-
- if (adt) {
- bAnimVizSettings *avs;
-
- /* get pointer to animviz settings for each target */
- if (mpt->pchan)
- avs = &mpt->ob->pose->avs;
- else
- avs = &mpt->ob->avs;
-
- /* it is assumed that keyframes for bones are all grouped in a single group
- * unless an option is set to always use the whole action
- */
- if ((mpt->pchan) && (avs->path_viewflag & MOTIONPATH_VIEW_KFACT) == 0) {
- bActionGroup *agrp = BKE_action_group_find_name(adt->action, mpt->pchan->name);
-
- if (agrp) {
- agroup_to_keylist(adt, agrp, &mpt->keys, 0);
- }
- }
- else {
- action_to_keylist(adt, adt->action, &mpt->keys, 0);
- }
- }
- }
-
- /* calculate path over requested range */
- CLOG_INFO(&LOG, 1, "Calculating MotionPaths between frames %d - %d (%d frames)", sfra, efra, efra - sfra + 1);
- for (CFRA = sfra; CFRA <= efra; CFRA++) {
- if (current_frame_only) {
- /* For current frame, only update tagged. */
- BKE_scene_graph_update_tagged(depsgraph, bmain);
- }
- else {
- /* Update relevant data for new frame. */
- motionpaths_calc_update_scene(bmain, depsgraph);
- }
-
- /* perform baking for targets */
- motionpaths_calc_bake_targets(targets, CFRA);
- }
-
- /* reset original environment */
- /* NOTE: We don't always need to reevaluate the main scene, as the depsgraph
- * may be a temporary one that works on a subset of the data. We always have
- * to resoture the current frame though. */
- CFRA = cfra;
- if (!current_frame_only && restore) {
- motionpaths_calc_update_scene(bmain, depsgraph);
- }
-
- /* clear recalc flags from targets */
- for (MPathTarget *mpt = targets->first; mpt; mpt = mpt->next) {
- bAnimVizSettings *avs;
- bMotionPath *mpath = mpt->mpath;
-
- /* get pointer to animviz settings for each target */
- if (mpt->pchan)
- avs = &mpt->ob->pose->avs;
- else
- avs = &mpt->ob->avs;
-
- /* clear the flag requesting recalculation of targets */
- avs->recalc &= ~ANIMVIZ_RECALC_PATHS;
-
- /* Clean temp data */
- BLI_dlrbTree_free(&mpt->keys);
-
- /* Free previous batches to force update. */
- GPU_VERTBUF_DISCARD_SAFE(mpath->points_vbo);
- GPU_BATCH_DISCARD_SAFE(mpath->batch_line);
- GPU_BATCH_DISCARD_SAFE(mpath->batch_points);
- }
-}
-
/* ******************************************************************** */
/* Curve Paths - for curve deforms and/or curve following */
diff --git a/source/blender/editors/animation/CMakeLists.txt b/source/blender/editors/animation/CMakeLists.txt
index a8de87e44e9..ea37aab69ea 100644
--- a/source/blender/editors/animation/CMakeLists.txt
+++ b/source/blender/editors/animation/CMakeLists.txt
@@ -25,6 +25,7 @@ set(INC
../../makesdna
../../makesrna
../../windowmanager
+ ../../../../intern/clog
../../../../intern/guardedalloc
../../../../intern/glew-mx
)
@@ -41,6 +42,7 @@ set(SRC
anim_filter.c
anim_ipo_utils.c
anim_markers.c
+ anim_motion_paths.c
anim_ops.c
drivers.c
fmodifier_ui.c
diff --git a/source/blender/editors/animation/anim_motion_paths.c b/source/blender/editors/animation/anim_motion_paths.c
new file mode 100644
index 00000000000..7023a138c96
--- /dev/null
+++ b/source/blender/editors/animation/anim_motion_paths.c
@@ -0,0 +1,335 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+/** \file
+ * \ingroup bke
+ */
+
+#include "MEM_guardedalloc.h"
+
+#include <stdlib.h>
+
+#include "BLI_listbase.h"
+#include "BLI_math.h"
+#include "BLI_dlrbTree.h"
+
+#include "DNA_anim_types.h"
+#include "DNA_armature_types.h"
+#include "DNA_scene_types.h"
+
+#include "BKE_animsys.h"
+#include "BKE_action.h"
+#include "BKE_main.h"
+#include "BKE_scene.h"
+
+#include "DEG_depsgraph.h"
+#include "DEG_depsgraph_query.h"
+
+#include "GPU_batch.h"
+#include "GPU_vertex_buffer.h"
+
+#include "ED_anim_api.h"
+#include "ED_keyframes_draw.h"
+
+#include "CLG_log.h"
+
+static CLG_LogRef LOG = {"ed.anim.motion_paths"};
+
+
+/* Motion path needing to be baked (mpt) */
+typedef struct MPathTarget {
+ struct MPathTarget *next, *prev;
+
+ bMotionPath *mpath; /* motion path in question */
+
+ DLRBT_Tree keys; /* temp, to know where the keyframes are */
+
+ /* Original (Source Objects) */
+ Object *ob; /* source object */
+ bPoseChannel *pchan; /* source posechannel (if applicable) */
+
+ /* "Evaluated" Copies (these come from the background COW copie
+ * that provide all the coordinates we want to save off)
+ */
+ Object *ob_eval; /* evaluated object */
+} MPathTarget;
+
+/* ........ */
+
+/* get list of motion paths to be baked for the given object
+ * - assumes the given list is ready to be used
+ */
+/* TODO: it would be nice in future to be able to update objects dependent on these bones too? */
+void animviz_get_object_motionpaths(Object *ob, ListBase *targets)
+{
+ MPathTarget *mpt;
+
+ /* object itself first */
+ if ((ob->avs.recalc & ANIMVIZ_RECALC_PATHS) && (ob->mpath)) {
+ /* new target for object */
+ mpt = MEM_callocN(sizeof(MPathTarget), "MPathTarget Ob");
+ BLI_addtail(targets, mpt);
+
+ mpt->mpath = ob->mpath;
+ mpt->ob = ob;
+ }
+
+ /* bones */
+ if ((ob->pose) && (ob->pose->avs.recalc & ANIMVIZ_RECALC_PATHS)) {
+ bArmature *arm = ob->data;
+ bPoseChannel *pchan;
+
+ for (pchan = ob->pose->chanbase.first; pchan; pchan = pchan->next) {
+ if ((pchan->bone) && (arm->layer & pchan->bone->layer) && (pchan->mpath)) {
+ /* new target for bone */
+ mpt = MEM_callocN(sizeof(MPathTarget), "MPathTarget PoseBone");
+ BLI_addtail(targets, mpt);
+
+ mpt->mpath = pchan->mpath;
+ mpt->ob = ob;
+ mpt->pchan = pchan;
+ }
+ }
+ }
+}
+
+/* ........ */
+
+/* update scene for current frame */
+static void motionpaths_calc_update_scene(Main *bmain,
+ struct Depsgraph *depsgraph)
+{
+ /* Do all updates
+ * - if this is too slow, resort to using a more efficient way
+ * that doesn't force complete update, but for now, this is the
+ * most accurate way!
+ *
+ * TODO(segey): Bring back partial updates, which became impossible
+ * with the new depsgraph due to unsorted nature of bases.
+ *
+ * TODO(sergey): Use evaluation context dedicated to motion paths.
+ */
+ BKE_scene_graph_update_for_newframe(depsgraph, bmain);
+}
+
+/* ........ */
+
+/* perform baking for the targets on the current frame */
+static void motionpaths_calc_bake_targets(ListBase *targets, int cframe)
+{
+ MPathTarget *mpt;
+
+ /* for each target, check if it can be baked on the current frame */
+ for (mpt = targets->first; mpt; mpt = mpt->next) {
+ bMotionPath *mpath = mpt->mpath;
+
+ /* current frame must be within the range the cache works for
+ * - is inclusive of the first frame, but not the last otherwise we get buffer overruns
+ */
+ if ((cframe < mpath->start_frame) || (cframe >= mpath->end_frame)) {
+ continue;
+ }
+
+ /* get the relevant cache vert to write to */
+ bMotionPathVert *mpv = mpath->points + (cframe - mpath->start_frame);
+
+ Object *ob_eval = mpt->ob_eval;
+
+ /* Lookup evaluated pose channel, here because the depsgraph
+ * evaluation can change them so they are not cached in mpt. */
+ bPoseChannel *pchan_eval = NULL;
+ if (mpt->pchan) {
+ pchan_eval = BKE_pose_channel_find_name(ob_eval->pose, mpt->pchan->name);
+ }
+
+ /* pose-channel or object path baking? */
+ if (pchan_eval) {
+ /* heads or tails */
+ if (mpath->flag & MOTIONPATH_FLAG_BHEAD) {
+ copy_v3_v3(mpv->co, pchan_eval->pose_head);
+ }
+ else {
+ copy_v3_v3(mpv->co, pchan_eval->pose_tail);
+ }
+
+ /* result must be in worldspace */
+ mul_m4_v3(ob_eval->obmat, mpv->co);
+ }
+ else {
+ /* worldspace object location */
+ copy_v3_v3(mpv->co, ob_eval->obmat[3]);
+ }
+
+ float mframe = (float)(cframe);
+
+ /* Tag if it's a keyframe */
+ if (BLI_dlrbTree_search_exact(&mpt->keys, compare_ak_cfraPtr, &mframe)) {
+ mpv->flag |= MOTIONPATH_VERT_KEY;
+ }
+ else {
+ mpv->flag &= ~MOTIONPATH_VERT_KEY;
+ }
+
+ /* Incremental update on evaluated object if possible, for fast updating
+ * while dragging in transform. */
+ bMotionPath *mpath_eval = NULL;
+ if (mpt->pchan) {
+ mpath_eval = (pchan_eval) ? pchan_eval->mpath : NULL;
+ }
+ else {
+ mpath_eval = ob_eval->mpath;
+ }
+
+ if (mpath_eval && mpath_eval->length == mpath->length) {
+ bMotionPathVert *mpv_eval = mpath_eval->points + (cframe - mpath_eval->start_frame);
+ *mpv_eval = *mpv;
+
+ GPU_VERTBUF_DISCARD_SAFE(mpath_eval->points_vbo);
+ GPU_BATCH_DISCARD_SAFE(mpath_eval->batch_line);
+ GPU_BATCH_DISCARD_SAFE(mpath_eval->batch_points);
+ }
+ }
+}
+
+/* Perform baking of the given object's and/or its bones' transforms to motion paths
+ * - scene: current scene
+ * - ob: object whose flagged motionpaths should get calculated
+ * - recalc: whether we need to
+ */
+/* TODO: include reports pointer? */
+void animviz_calc_motionpaths(Depsgraph *depsgraph,
+ Main *bmain,
+ Scene *scene,
+ ListBase *targets,
+ bool restore,
+ bool current_frame_only)
+{
+ /* sanity check */
+ if (ELEM(NULL, targets, targets->first))
+ return;
+
+ /* Compute frame range to bake within.
+ * TODO: this method could be improved...
+ * 1) max range for standard baking
+ * 2) minimum range for recalc baking (i.e. between keyframes, but how?) */
+ int sfra = INT_MAX;
+ int efra = INT_MIN;
+
+ for (MPathTarget *mpt = targets->first; mpt; mpt = mpt->next) {
+ /* try to increase area to do (only as much as needed) */
+ sfra = MIN2(sfra, mpt->mpath->start_frame);
+ efra = MAX2(efra, mpt->mpath->end_frame);
+ }
+
+ if (efra <= sfra) {
+ return;
+ }
+
+ /* Limit frame range if we are updating just the current frame. */
+ /* set frame values */
+ int cfra = CFRA;
+ if (current_frame_only) {
+ if (cfra < sfra || cfra > efra) {
+ return;
+ }
+ sfra = efra = cfra;
+ }
+
+ /* get copies of objects/bones to get the calculated results from
+ * (for copy-on-write evaluation), so that we actually get some results
+ */
+ // TODO: Create a copy of background depsgraph that only contain these entities, and only evaluates them..
+ for (MPathTarget *mpt = targets->first; mpt; mpt = mpt->next) {
+ mpt->ob_eval = DEG_get_evaluated_object(depsgraph, mpt->ob);
+
+ AnimData *adt = BKE_animdata_from_id(&mpt->ob_eval->id);
+
+ /* build list of all keyframes in active action for object or pchan */
+ BLI_dlrbTree_init(&mpt->keys);
+
+ if (adt) {
+ bAnimVizSettings *avs;
+
+ /* get pointer to animviz settings for each target */
+ if (mpt->pchan)
+ avs = &mpt->ob->pose->avs;
+ else
+ avs = &mpt->ob->avs;
+
+ /* it is assumed that keyframes for bones are all grouped in a single group
+ * unless an option is set to always use the whole action
+ */
+ if ((mpt->pchan) && (avs->path_viewflag & MOTIONPATH_VIEW_KFACT) == 0) {
+ bActionGroup *agrp = BKE_action_group_find_name(adt->action, mpt->pchan->name);
+
+ if (agrp) {
+ agroup_to_keylist(adt, agrp, &mpt->keys, 0);
+ }
+ }
+ else {
+ action_to_keylist(adt, adt->action, &mpt->keys, 0);
+ }
+ }
+ }
+
+ /* calculate path over requested range */
+ CLOG_INFO(&LOG, 1, "Calculating MotionPaths between frames %d - %d (%d frames)", sfra, efra, efra - sfra + 1);
+ for (CFRA = sfra; CFRA <= efra; CFRA++) {
+ if (current_frame_only) {
+ /* For current frame, only update tagged. */
+ BKE_scene_graph_update_tagged(depsgraph, bmain);
+ }
+ else {
+ /* Update relevant data for new frame. */
+ motionpaths_calc_update_scene(bmain, depsgraph);
+ }
+
+ /* perform baking for targets */
+ motionpaths_calc_bake_targets(targets, CFRA);
+ }
+
+ /* reset original environment */
+ /* NOTE: We don't always need to reevaluate the main scene, as the depsgraph
+ * may be a temporary one that works on a subset of the data. We always have
+ * to resoture the current frame though. */
+ CFRA = cfra;
+ if (!current_frame_only && restore) {
+ motionpaths_calc_update_scene(bmain, depsgraph);
+ }
+
+ /* clear recalc flags from targets */
+ for (MPathTarget *mpt = targets->first; mpt; mpt = mpt->next) {
+ bAnimVizSettings *avs;
+ bMotionPath *mpath = mpt->mpath;
+
+ /* get pointer to animviz settings for each target */
+ if (mpt->pchan)
+ avs = &mpt->ob->pose->avs;
+ else
+ avs = &mpt->ob->avs;
+
+ /* clear the flag requesting recalculation of targets */
+ avs->recalc &= ~ANIMVIZ_RECALC_PATHS;
+
+ /* Clean temp data */
+ BLI_dlrbTree_free(&mpt->keys);
+
+ /* Free previous batches to force update. */
+ GPU_VERTBUF_DISCARD_SAFE(mpath->points_vbo);
+ GPU_BATCH_DISCARD_SAFE(mpath->batch_line);
+ GPU_BATCH_DISCARD_SAFE(mpath->batch_points);
+ }
+}
diff --git a/source/blender/editors/armature/pose_edit.c b/source/blender/editors/armature/pose_edit.c
index 5920a69c60b..9323e00db65 100644
--- a/source/blender/editors/armature/pose_edit.c
+++ b/source/blender/editors/armature/pose_edit.c
@@ -54,6 +54,7 @@
#include "WM_api.h"
#include "WM_types.h"
+#include "ED_anim_api.h"
#include "ED_armature.h"
#include "ED_keyframing.h"
#include "ED_screen.h"
diff --git a/source/blender/editors/include/ED_anim_api.h b/source/blender/editors/include/ED_anim_api.h
index 6dccc55d3ff..a9dce0a0542 100644
--- a/source/blender/editors/include/ED_anim_api.h
+++ b/source/blender/editors/include/ED_anim_api.h
@@ -792,4 +792,13 @@ void ED_drivers_editor_init(struct bContext *C, struct ScrArea *sa);
/* ************************************************ */
+void animviz_calc_motionpaths(struct Depsgraph *depsgraph,
+ struct Main *bmain,
+ struct Scene *scene,
+ ListBase *targets,
+ bool restore,
+ bool current_frame_only);
+
+void animviz_get_object_motionpaths(struct Object *ob, ListBase *targets);
+
#endif /* __ED_ANIM_API_H__ */
diff --git a/source/blender/editors/object/object_edit.c b/source/blender/editors/object/object_edit.c
index 7950e79162d..ce1a7306773 100644
--- a/source/blender/editors/object/object_edit.c
+++ b/source/blender/editors/object/object_edit.c
@@ -83,6 +83,7 @@
#include "DEG_depsgraph.h"
#include "DEG_depsgraph_build.h"
+#include "ED_anim_api.h"
#include "ED_armature.h"
#include "ED_curve.h"
#include "ED_mesh.h"
diff --git a/source/blender/python/intern/CMakeLists.txt b/source/blender/python/intern/CMakeLists.txt
index f8b493b05d4..3563300b515 100644
--- a/source/blender/python/intern/CMakeLists.txt
+++ b/source/blender/python/intern/CMakeLists.txt
@@ -118,6 +118,7 @@ set(SRC
)
set(LIB
+ bf_editor_animation
bf_editor_interface
bf_editor_space_api
bf_python_gpu