[Bf-blender-cvs] [415910a7e08] arcpatch-D9019: Make the operators that change keyframe data update the motion paths

Octave C noreply at git.blender.org
Tue Oct 13 13:15:03 CEST 2020


Commit: 415910a7e08cc77a869bee6002c80a9ff1064388
Author: Octave C
Date:   Tue Oct 13 13:11:30 2020 +0200
Branches: arcpatch-D9019
https://developer.blender.org/rB415910a7e08cc77a869bee6002c80a9ff1064388

Make the operators that change keyframe data update the motion paths

**Problem **

Right now, when auto-keying is on and and one transforms an object in the 3d view, its motion paths get updated. This makes it easy to iterate over an animation and make sure the object's trajectory looks right.

However, when the animation data is updated in any other way (e.g. through the graph editor, timeline, or action editor), the motion paths don't get updated right away, requiring an extra manual refresh on each incremental change.

**Proposed solution **

This patch makes sure that motion paths get updated whenever keyframe data changes, allowing for easier incremental changes. For now, the active object's motion paths are recomputed on every edit that triggers an "ND_KEYFRAME_PROP" notifier.

**Before**

{F8944697}

**After**

{F8944698}

Performance is fine now, there is no noticeable slow down with the Rain scene. Earlier it was slow because I was updating every point on the motion path as the mouse was moving, but now (as of diff 29494) only a single point is moved interactively and the whole path gets updated once the transform is confirmed, which matches what happens with viewport updates.

Here is a stress test, with a dozen motion paths having each 100 frames. I'm not an animator, so please excuse the wonkiness of it :)

{F8965509}

I've also tried moving around the keyframes in the timeline and dope sheet, and there isn't a noticeable slow down there either, which makes sense because the code that runs is almost the same each time (tiny bit of setup + a call to ED_objects_and_pose_recalculate_paths). For very large updates, say, selecting every single keyframe of every single bone and changing their handle type at once, there is a lag of about half a second (on a Ryzen 3600 with a debug build), which in my opinion i [...]

Reviewed By: looch

Differential Revision: https://developer.blender.org/D9019

===================================================================

M	source/blender/editors/include/ED_object.h
M	source/blender/editors/object/object_edit.c
M	source/blender/editors/space_action/action_edit.c
M	source/blender/editors/space_graph/graph_edit.c
M	source/blender/editors/transform/transform_convert_action.c
M	source/blender/editors/transform/transform_convert_graph.c
M	source/blender/editors/transform/transform_convert_nla.c
M	source/blender/editors/transform/transform_convert_object.c

===================================================================

diff --git a/source/blender/editors/include/ED_object.h b/source/blender/editors/include/ED_object.h
index 6fdd65fdcc9..c4b465ec023 100644
--- a/source/blender/editors/include/ED_object.h
+++ b/source/blender/editors/include/ED_object.h
@@ -25,6 +25,7 @@
 
 #include "BLI_compiler_attrs.h"
 #include "DNA_object_enums.h"
+#include "ED_anim_api.h"
 
 #ifdef __cplusplus
 extern "C" {
@@ -62,10 +63,11 @@ struct Object *ED_object_context(const struct bContext *C);
 struct Object *ED_object_active_context(const struct bContext *C);
 void ED_collection_hide_menu_draw(const struct bContext *C, struct uiLayout *layout);
 
-Object **ED_object_array_in_mode_or_selected(struct bContext *C,
-                                             bool (*filter_fn)(struct Object *ob, void *user_data),
-                                             void *filter_user_data,
-                                             uint *r_objects_len);
+struct Object **ED_object_array_in_mode_or_selected(struct bContext *C,
+                                                    bool (*filter_fn)(struct Object *ob,
+                                                                      void *user_data),
+                                                    void *filter_user_data,
+                                                    uint *r_objects_len);
 
 /* object_utils.c */
 bool ED_object_calc_active_center_for_editmode(struct Object *obedit,
@@ -229,18 +231,22 @@ void ED_object_vpaintmode_exit(struct bContext *C);
 void ED_object_wpaintmode_exit_ex(struct Object *ob);
 void ED_object_wpaintmode_exit(struct bContext *C);
 
-void ED_object_texture_paint_mode_enter_ex(struct Main *bmain, struct Scene *scene, Object *ob);
+void ED_object_texture_paint_mode_enter_ex(struct Main *bmain,
+                                           struct Scene *scene,
+                                           struct Object *ob);
 void ED_object_texture_paint_mode_enter(struct bContext *C);
 
-void ED_object_texture_paint_mode_exit_ex(struct Main *bmain, struct Scene *scene, Object *ob);
+void ED_object_texture_paint_mode_exit_ex(struct Main *bmain,
+                                          struct Scene *scene,
+                                          struct Object *ob);
 void ED_object_texture_paint_mode_exit(struct bContext *C);
 
 void ED_object_particle_edit_mode_enter_ex(struct Depsgraph *depsgraph,
                                            struct Scene *scene,
-                                           Object *ob);
+                                           struct Object *ob);
 void ED_object_particle_edit_mode_enter(struct bContext *C);
 
-void ED_object_particle_edit_mode_exit_ex(struct Scene *scene, Object *ob);
+void ED_object_particle_edit_mode_exit_ex(struct Scene *scene, struct Object *ob);
 void ED_object_particle_edit_mode_exit(struct bContext *C);
 
 void ED_object_sculptmode_enter_ex(struct Main *bmain,
@@ -321,6 +327,9 @@ typedef enum eObjectPathCalcRange {
 void ED_objects_recalculate_paths(struct bContext *C,
                                   struct Scene *scene,
                                   eObjectPathCalcRange range);
+void ED_objects_and_pose_recalculate_paths(struct bContext *C,
+                                           struct Scene *scene,
+                                           enum eAnimvizCalcRange animviz_range);
 
 /* constraints */
 struct ListBase *ED_object_constraint_active_list(struct Object *ob);
diff --git a/source/blender/editors/object/object_edit.c b/source/blender/editors/object/object_edit.c
index 3e7f028bd95..6e6960656f8 100644
--- a/source/blender/editors/object/object_edit.c
+++ b/source/blender/editors/object/object_edit.c
@@ -1020,7 +1020,7 @@ void OBJECT_OT_forcefield_toggle(wmOperatorType *ot)
 /** \name Calculate Motion Paths Operator
  * \{ */
 
-static eAnimvizCalcRange object_path_convert_range(eObjectPathCalcRange range)
+static eAnimvizCalcRange path_convert_object_to_animviz_range(eObjectPathCalcRange range)
 {
   switch (range) {
     case OBJECT_PATH_CALC_RANGE_CURRENT_FRAME:
@@ -1033,6 +1033,32 @@ static eAnimvizCalcRange object_path_convert_range(eObjectPathCalcRange range)
   return ANIMVIZ_CALC_RANGE_FULL;
 }
 
+static eObjectPathCalcRange path_convert_animviz_to_object_range(eAnimvizCalcRange range)
+{
+  switch (range) {
+    case ANIMVIZ_CALC_RANGE_CURRENT_FRAME:
+      return OBJECT_PATH_CALC_RANGE_CURRENT_FRAME;
+    case ANIMVIZ_CALC_RANGE_CHANGED:
+      return OBJECT_PATH_CALC_RANGE_CHANGED;
+    case ANIMVIZ_CALC_RANGE_FULL:
+      return OBJECT_PATH_CALC_RANGE_FULL;
+  }
+  return OBJECT_PATH_CALC_RANGE_FULL;
+}
+
+static ePosePathCalcRange path_convert_animviz_to_pose_range(eAnimvizCalcRange range)
+{
+  switch (range) {
+    case ANIMVIZ_CALC_RANGE_CURRENT_FRAME:
+      return POSE_PATH_CALC_RANGE_CURRENT_FRAME;
+    case ANIMVIZ_CALC_RANGE_CHANGED:
+      return POSE_PATH_CALC_RANGE_CHANGED;
+    case ANIMVIZ_CALC_RANGE_FULL:
+      return POSE_PATH_CALC_RANGE_FULL;
+  }
+  return POSE_PATH_CALC_RANGE_FULL;
+}
+
 /* For the objects with animation: update paths for those that have got them
  * This should selectively update paths that exist...
  *
@@ -1074,7 +1100,7 @@ void ED_objects_recalculate_paths(bContext *C, Scene *scene, eObjectPathCalcRang
 
   /* recalculate paths, then free */
   animviz_calc_motionpaths(
-      depsgraph, bmain, scene, &targets, object_path_convert_range(range), true);
+      depsgraph, bmain, scene, &targets, path_convert_object_to_animviz_range(range), true);
   BLI_freelistN(&targets);
 
   if (range != OBJECT_PATH_CALC_RANGE_CURRENT_FRAME) {
@@ -1094,6 +1120,29 @@ void ED_objects_recalculate_paths(bContext *C, Scene *scene, eObjectPathCalcRang
   }
 }
 
+/* Combines ED_objects_recalculate_paths and ED_pose_recalculate_paths in a single function.
+ * Useful for updates from tools that may change a lot of animation data at once (e.g. time line,
+ * graph editor)
+ */
+void ED_objects_and_pose_recalculate_paths(bContext *C,
+                                           Scene *scene,
+                                           eAnimvizCalcRange animviz_range)
+{
+  eObjectPathCalcRange object_range = path_convert_animviz_to_object_range(animviz_range);
+  ePosePathCalcRange pose_range = path_convert_animviz_to_pose_range(animviz_range);
+
+  ED_objects_recalculate_paths(C, scene, object_range);
+
+  /* Loop over objects in the scene. */
+  CTX_DATA_BEGIN (C, Object *, ob, selected_editable_objects) {
+    /* If they have pose data, update their bones' motion paths. */
+    if (ob->pose) {
+      ED_pose_recalculate_paths(C, scene, ob, pose_range);
+    }
+  }
+  CTX_DATA_END;
+}
+
 /* show popup to determine settings */
 static int object_calculate_paths_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
 {
diff --git a/source/blender/editors/space_action/action_edit.c b/source/blender/editors/space_action/action_edit.c
index e14e78912d7..c1f2698dd2b 100644
--- a/source/blender/editors/space_action/action_edit.c
+++ b/source/blender/editors/space_action/action_edit.c
@@ -51,16 +51,19 @@
 #include "BKE_gpencil.h"
 #include "BKE_key.h"
 #include "BKE_nla.h"
+#include "BKE_object.h"
 #include "BKE_report.h"
 
 #include "UI_view2d.h"
 
 #include "ED_anim_api.h"
+#include "ED_armature.h"
 #include "ED_gpencil.h"
 #include "ED_keyframes_edit.h"
 #include "ED_keyframing.h"
 #include "ED_markers.h"
 #include "ED_mask.h"
+#include "ED_object.h"
 #include "ED_screen.h"
 
 #include "WM_api.h"
@@ -1298,6 +1301,10 @@ static int actkeys_expo_exec(bContext *C, wmOperator *op)
   /* set notifier that keyframe properties have changed */
   WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME_PROP, NULL);
 
+  /* Recalculate motion paths if objects have them. */
+  Scene *scene = CTX_data_scene(C);
+  ED_objects_and_pose_recalculate_paths(C, scene, ANIMVIZ_CALC_RANGE_CHANGED);
+
   return OPERATOR_FINISHED;
 }
 
@@ -1349,6 +1356,10 @@ static int actkeys_ipo_exec(bContext *C, wmOperator *op)
   /* set notifier that keyframe properties have changed */
   WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME_PROP, NULL);
 
+  /* Recalculate motion paths if objects have them. */
+  Scene *scene = CTX_data_scene(C);
+  ED_objects_and_pose_recalculate_paths(C, scene, ANIMVIZ_CALC_RANGE_CHANGED);
+
   return OPERATOR_FINISHED;
 }
 
@@ -1397,6 +1408,10 @@ static int actkeys_easing_exec(bContext *C, wmOperator *op)
   /* set notifier that keyframe properties have changed */
   WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME_PROP, NULL);
 
+  /* Recalculate motion paths if objects have them. */
+  Scene *scene = CTX_data_scene(C);
+  ED_objects_and_pose_recalculate_paths(C, scene, ANIMVIZ_CALC_RANGE_CHANGED);
+
   return OPERATOR_FINISHED;
 }
 
@@ -1484,6 +1499,10 @@ static int actkeys_handletype_exec(bContext *C, wmOperator *op)
   /* set notifier that keyframe properties have changed */
   WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME_PROP, NULL);
 
+  /* Recalculate motion paths if objects have them. */
+  Scene *scene = CTX_data_scene(C);
+  ED_objects_and_pose_recalculate_paths(C, scene, ANIMVIZ_CALC_RANGE_CHANGED);
+
   return OPERATOR_FINISHED;
 }
 
@@ -1590,6 +1609,10 @@ static int actkeys_keytype_exec(bContext *C, wmOperator *op)
   /* set notifier that keyframe properties have changed */
   WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME_PROP, NULL);
 
+  /* Recalculate motion paths if objects have them. */
+  Scene *scene = CTX_data_scene(C);
+  ED_objects_and_pose_recalculate_paths(C, scene, ANIMVIZ_CALC_RANGE_CHANGED);
+
   return OPERATOR_FINISHED;
 }
 
diff --git a/source/blender/editors/space_graph/graph_edit.c b/source/blender/editors/space_graph/graph_edit.c
index 9fe6b4e06f6..f8a8f198e11 100644
--- a/source/blender/editors/space_graph/graph_edit.c
+++ b/source/blender/editors/space_graph/graph_edit.c
@@ -50,6 +50,7 @@
 #include "BKE_fcurve.h"
 #include "BKE_global.h"
 #include "BKE_nla.h"
+#include "BKE_object.h"
 #include "BKE_report.h"
 
 #include "DEG_depsgraph_build.h"
@@ -58,10 +59,12 @@
 #include "UI_view2d.h"
 
 #include "ED_anim_api.h"
+#include "ED_armature.h"
 #include "ED_keyframes_edit.h"
 #include "ED_keyframing.h"
 #include "ED_markers.h"
 #include "ED_numinp

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list