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. @@

_______________________________________________
Bf-blender-cvs mailing list
Bf-blender-cvs@blender.org
https://lists.blender.org/mailman/listinfo/bf-blender-cvs

Reply via email to