Motion paths: Refactor, make update range more explicit
authorSergey Sharybin <sergey.vfx@gmail.com>
Fri, 20 Sep 2019 10:48:28 +0000 (12:48 +0200)
committerSergey Sharybin <sergey.vfx@gmail.com>
Wed, 25 Sep 2019 12:40:05 +0000 (14:40 +0200)
Allows to have a higher versatility in the API.

Should be no functional changes.

source/blender/editors/animation/anim_motion_paths.c
source/blender/editors/armature/pose_edit.c
source/blender/editors/armature/pose_transform.c
source/blender/editors/armature/pose_utils.c
source/blender/editors/include/ED_anim_api.h
source/blender/editors/include/ED_armature.h
source/blender/editors/include/ED_object.h
source/blender/editors/object/object_edit.c
source/blender/editors/transform/transform_convert.c
source/blender/editors/transform/transform_generics.c

index 33be56ce870a7ba04eb0fc65b437dc5cb1d242be..9d94b14250aaffa4255d8ed566eb13420b2c6536 100644 (file)
@@ -220,8 +220,8 @@ void animviz_calc_motionpaths(Depsgraph *depsgraph,
                               Main *bmain,
                               Scene *scene,
                               ListBase *targets,
-                              bool restore,
-                              bool current_frame_only)
+                              eAnimvizCalcRange range,
+                              bool restore)
 {
   /* sanity check */
   if (ELEM(NULL, targets, targets->first)) {
@@ -248,7 +248,7 @@ void animviz_calc_motionpaths(Depsgraph *depsgraph,
   /* Limit frame range if we are updating just the current frame. */
   /* set frame values */
   int cfra = CFRA;
-  if (current_frame_only) {
+  if (range == ANIMVIZ_CALC_RANGE_CURRENT_FRAME) {
     if (cfra < sfra || cfra > efra) {
       return;
     }
@@ -308,7 +308,7 @@ void animviz_calc_motionpaths(Depsgraph *depsgraph,
             efra,
             efra - sfra + 1);
   for (CFRA = sfra; CFRA <= efra; CFRA++) {
-    if (current_frame_only) {
+    if (range == ANIMVIZ_CALC_RANGE_CURRENT_FRAME) {
       /* For current frame, only update tagged. */
       BKE_scene_graph_update_tagged(depsgraph, bmain);
     }
@@ -326,7 +326,7 @@ void animviz_calc_motionpaths(Depsgraph *depsgraph,
    * may be a temporary one that works on a subset of the data.
    * We always have to restore the current frame though. */
   CFRA = cfra;
-  if (!current_frame_only && restore) {
+  if (range != ANIMVIZ_CALC_RANGE_CURRENT_FRAME && restore) {
     motionpaths_calc_update_scene(bmain, depsgraph);
   }
 
index 8f4896c0b82f49252b886d469b578d9990be44ff..e2c9828c20f918e39235fb02262fabfac0561c7b 100644 (file)
@@ -182,12 +182,25 @@ static bool pose_has_protected_selected(Object *ob, short warn)
 /* ********************************************** */
 /* Motion Paths */
 
+static eAnimvizCalcRange pose_path_convert_range(ePosePathCalcRange range)
+{
+  switch (range) {
+    case POSE_PATH_CALC_RANGE_CURRENT_FRAME:
+      return ANIMVIZ_CALC_RANGE_CURRENT_FRAME;
+    case POSE_PATH_CALC_RANGE_CHANGED:
+      return ANIMVIZ_CALC_RANGE_CHANGED;
+    case POSE_PATH_CALC_RANGE_FULL:
+      return ANIMVIZ_CALC_RANGE_FULL;
+  }
+  return ANIMVIZ_CALC_RANGE_FULL;
+}
+
 /* For the object with pose/action: update paths for those that have got them
  * This should selectively update paths that exist...
  *
  * To be called from various tools that do incremental updates
  */
-void ED_pose_recalculate_paths(bContext *C, Scene *scene, Object *ob, bool current_frame_only)
+void ED_pose_recalculate_paths(bContext *C, Scene *scene, Object *ob, ePosePathCalcRange range)
 {
   /* Transform doesn't always have context available to do update. */
   if (C == NULL) {
@@ -210,7 +223,8 @@ void ED_pose_recalculate_paths(bContext *C, Scene *scene, Object *ob, bool curre
   TIMEIT_START(pose_path_calc);
 #endif
 
-  animviz_calc_motionpaths(depsgraph, bmain, scene, &targets, !free_depsgraph, current_frame_only);
+  animviz_calc_motionpaths(
+      depsgraph, bmain, scene, &targets, pose_path_convert_range(range), !free_depsgraph);
 
 #ifdef DEBUG_TIME
   TIMEIT_END(pose_path_calc);
@@ -218,7 +232,7 @@ void ED_pose_recalculate_paths(bContext *C, Scene *scene, Object *ob, bool curre
 
   BLI_freelistN(&targets);
 
-  if (!current_frame_only) {
+  if (range != POSE_PATH_CALC_RANGE_CURRENT_FRAME) {
     /* Tag armature object for copy on write - so paths will draw/redraw.
      * For currently frame only we update evaluated object directly. */
     DEG_id_tag_update(&ob->id, ID_RECALC_COPY_ON_WRITE);
@@ -293,7 +307,7 @@ static int pose_calculate_paths_exec(bContext *C, wmOperator *op)
 
   /* calculate the bones that now have motionpaths... */
   /* TODO: only make for the selected bones? */
-  ED_pose_recalculate_paths(C, scene, ob, false);
+  ED_pose_recalculate_paths(C, scene, ob, POSE_PATH_CALC_RANGE_FULL);
 
 #ifdef DEBUG_TIME
   TIMEIT_END(recalc_pose_paths);
@@ -371,7 +385,7 @@ static int pose_update_paths_exec(bContext *C, wmOperator *UNUSED(op))
 
   /* calculate the bones that now have motionpaths... */
   /* TODO: only make for the selected bones? */
-  ED_pose_recalculate_paths(C, scene, ob, false);
+  ED_pose_recalculate_paths(C, scene, ob, POSE_PATH_CALC_RANGE_FULL);
 
   /* notifiers for updates */
   WM_event_add_notifier(C, NC_OBJECT | ND_POSE, ob);
index 52a3f7711c4128f6ccc3f6fc5aadca3e7fda3ee0..c03fc0415ef31f7930bbdf1df51740d464c11427 100644 (file)
@@ -831,7 +831,7 @@ static int pose_paste_exec(bContext *C, wmOperator *op)
 
   /* Recalculate paths if any of the bones have paths... */
   if ((ob->pose->avs.path_bakeflag & MOTIONPATH_BAKE_HAS_PATHS)) {
-    ED_pose_recalculate_paths(C, scene, ob, false);
+    ED_pose_recalculate_paths(C, scene, ob, POSE_PATH_CALC_RANGE_FULL);
   }
 
   /* Notifiers for updates, */
@@ -1112,7 +1112,7 @@ static int pose_clear_transform_generic_exec(bContext *C,
 
         /* now recalculate paths */
         if ((ob_iter->pose->avs.path_bakeflag & MOTIONPATH_BAKE_HAS_PATHS)) {
-          ED_pose_recalculate_paths(C, scene, ob_iter, false);
+          ED_pose_recalculate_paths(C, scene, ob_iter, POSE_PATH_CALC_RANGE_FULL);
         }
 
         BLI_freelistN(&dsources);
index fbaf2c896d041b1f62ba1b2142ff18c4803ca936..3f6db956643ac7618b8c439a84f9dfbe2feaa814 100644 (file)
@@ -327,7 +327,8 @@ void poseAnim_mapping_autoKeyframe(bContext *C, Scene *scene, ListBase *pfLinks,
     if (ob->id.tag & LIB_TAG_DOIT) {
       if (ob->pose->avs.path_bakeflag & MOTIONPATH_BAKE_HAS_PATHS) {
         // ED_pose_clear_paths(C, ob); // XXX for now, don't need to clear
-        ED_pose_recalculate_paths(C, scene, ob, false);
+        /* TODO(sergey): Should ensure we can use more narrow update range here. */
+        ED_pose_recalculate_paths(C, scene, ob, POSE_PATH_CALC_RANGE_FULL);
       }
     }
   }
index cb6c66ed7955ffcde2d502f7b364e1032d892888..c262f390dc6c3d7ebe1b7e2f791ffccb87d4e122 100644 (file)
@@ -834,12 +834,23 @@ void ED_drivers_editor_init(struct bContext *C, struct ScrArea *sa);
 
 /* ************************************************ */
 
+typedef enum eAnimvizCalcRange {
+  /* Update motion paths at the current frame only. */
+  ANIMVIZ_CALC_RANGE_CURRENT_FRAME,
+
+  /* Try to limit updates to a close neighborhood of the current frame. */
+  ANIMVIZ_CALC_RANGE_CHANGED,
+
+  /* Update an entire range of the motion paths. */
+  ANIMVIZ_CALC_RANGE_FULL,
+} eAnimvizCalcRange;
+
 void animviz_calc_motionpaths(struct Depsgraph *depsgraph,
                               struct Main *bmain,
                               struct Scene *scene,
                               ListBase *targets,
-                              bool restore,
-                              bool current_frame_only);
+                              eAnimvizCalcRange range,
+                              bool restore);
 
 void animviz_get_object_motionpaths(struct Object *ob, ListBase *targets);
 
index 173ba65fc47f2bc72862b32cb06ebebaaabd888d..7ac42967dda7c2f063eb1e1b4d2cc1b28c288ef0 100644 (file)
@@ -284,10 +284,18 @@ bool ED_pose_deselect_all_multi(struct bContext *C, int select_mode, const bool
 bool ED_pose_deselect_all(struct Object *ob, int select_mode, const bool ignore_visibility);
 void ED_pose_bone_select_tag_update(struct Object *ob);
 void ED_pose_bone_select(struct Object *ob, struct bPoseChannel *pchan, bool select);
+
+/* Corresponds to eAnimvizCalcRange. */
+typedef enum ePosePathCalcRange {
+  POSE_PATH_CALC_RANGE_CURRENT_FRAME,
+  POSE_PATH_CALC_RANGE_CHANGED,
+  POSE_PATH_CALC_RANGE_FULL,
+} ePosePathCalcRange;
 void ED_pose_recalculate_paths(struct bContext *C,
                                struct Scene *scene,
                                struct Object *ob,
-                               bool current_frame_only);
+                               ePosePathCalcRange range);
+
 struct Object *ED_pose_object_from_context(struct bContext *C);
 
 /* meshlaplacian.c */
index c481c19a5526a42ded5eb8cf2b3d8b465b75f1bc..38d75aa57e90e01995326aa8d56f3c2f581efee1 100644 (file)
@@ -238,9 +238,17 @@ void ED_object_single_user(struct Main *bmain, struct Scene *scene, struct Objec
 
 /* object motion paths */
 void ED_objects_clear_paths(struct bContext *C, bool only_selected);
+
+/* Corresponds to eAnimvizCalcRange. */
+typedef enum eObjectPathCalcRange {
+  OBJECT_PATH_CALC_RANGE_CURRENT_FRAME,
+  OBJECT_PATH_CALC_RANGE_CHANGED,
+  OBJECT_PATH_CALC_RANGE_FULL,
+} eObjectPathCalcRange;
+
 void ED_objects_recalculate_paths(struct bContext *C,
                                   struct Scene *scene,
-                                  bool current_frame_only);
+                                  eObjectPathCalcRange range);
 
 /* constraints */
 struct ListBase *get_active_constraints(struct Object *ob);
index 74abe104134f557126d0573e984062df018874d9..77897c909d97d49ac2859627b7dfbc54cbd15b9e 100644 (file)
@@ -910,12 +910,25 @@ void OBJECT_OT_forcefield_toggle(wmOperatorType *ot)
 /* ********************************************** */
 /* Motion Paths */
 
+static eAnimvizCalcRange object_path_convert_range(eObjectPathCalcRange range)
+{
+  switch (range) {
+    case OBJECT_PATH_CALC_RANGE_CURRENT_FRAME:
+      return ANIMVIZ_CALC_RANGE_CURRENT_FRAME;
+    case OBJECT_PATH_CALC_RANGE_CHANGED:
+      return ANIMVIZ_CALC_RANGE_CHANGED;
+    case OBJECT_PATH_CALC_RANGE_FULL:
+      return ANIMVIZ_CALC_RANGE_FULL;
+  }
+  return ANIMVIZ_CALC_RANGE_FULL;
+}
+
 /* For the objects with animation: update paths for those that have got them
  * This should selectively update paths that exist...
  *
  * To be called from various tools that do incremental updates
  */
-void ED_objects_recalculate_paths(bContext *C, Scene *scene, bool current_frame_only)
+void ED_objects_recalculate_paths(bContext *C, Scene *scene, eObjectPathCalcRange range)
 {
   /* Transform doesn't always have context available to do update. */
   if (C == NULL) {
@@ -937,10 +950,11 @@ void ED_objects_recalculate_paths(bContext *C, Scene *scene, bool current_frame_
   CTX_DATA_END;
 
   /* recalculate paths, then free */
-  animviz_calc_motionpaths(depsgraph, bmain, scene, &targets, true, current_frame_only);
+  animviz_calc_motionpaths(
+      depsgraph, bmain, scene, &targets, object_path_convert_range(range), true);
   BLI_freelistN(&targets);
 
-  if (!current_frame_only) {
+  if (range != OBJECT_PATH_CALC_RANGE_CURRENT_FRAME) {
     /* Tag objects for copy on write - so paths will draw/redraw
      * For currently frame only we update evaluated object directly. */
     CTX_DATA_BEGIN (C, Object *, ob, selected_editable_objects) {
@@ -995,7 +1009,7 @@ static int object_calculate_paths_exec(bContext *C, wmOperator *op)
   CTX_DATA_END;
 
   /* calculate the paths for objects that have them (and are tagged to get refreshed) */
-  ED_objects_recalculate_paths(C, scene, false);
+  ED_objects_recalculate_paths(C, scene, OBJECT_PATH_CALC_RANGE_FULL);
 
   /* notifiers for updates */
   WM_event_add_notifier(C, NC_OBJECT | ND_TRANSFORM, NULL);
@@ -1060,7 +1074,7 @@ static int object_update_paths_exec(bContext *C, wmOperator *UNUSED(op))
   }
 
   /* calculate the paths for objects that have them (and are tagged to get refreshed) */
-  ED_objects_recalculate_paths(C, scene, false);
+  ED_objects_recalculate_paths(C, scene, OBJECT_PATH_CALC_RANGE_FULL);
 
   /* notifiers for updates */
   WM_event_add_notifier(C, NC_OBJECT | ND_TRANSFORM, NULL);
index 67bb132972ecac41a11730e5040b975b6ed162a3..81b7c7f8c9e59da0a597d4020b7908541506c337 100644 (file)
@@ -2237,9 +2237,10 @@ void special_aftertrans_update(bContext *C, TransInfo *t)
     /* Update motion paths once for all transformed bones in an object. */
     GSetIterator gs_iter;
     GSET_ITER (gs_iter, motionpath_updates) {
-      bool current_frame_only = canceled;
+      const ePosePathCalcRange range = canceled ? POSE_PATH_CALC_RANGE_CURRENT_FRAME :
+                                                  POSE_PATH_CALC_RANGE_CHANGED;
       ob = BLI_gsetIterator_getKey(&gs_iter);
-      ED_pose_recalculate_paths(C, t->scene, ob, current_frame_only);
+      ED_pose_recalculate_paths(C, t->scene, ob, range);
     }
     BLI_gset_free(motionpath_updates, NULL);
   }
@@ -2320,8 +2321,9 @@ void special_aftertrans_update(bContext *C, TransInfo *t)
 
     if (motionpath_update) {
       /* Update motion paths once for all transformed objects. */
-      bool current_frame_only = canceled;
-      ED_objects_recalculate_paths(C, t->scene, current_frame_only);
+      const eObjectPathCalcRange range = canceled ? OBJECT_PATH_CALC_RANGE_CURRENT_FRAME :
+                                                    OBJECT_PATH_CALC_RANGE_CHANGED;
+      ED_objects_recalculate_paths(C, t->scene, range);
     }
   }
 
index 76f699e3dc4ab2308027b630f3f0b3f00334ea22..d05edb8d80596613cf9e4bc93cfc218ca05c25e8 100644 (file)
@@ -1088,7 +1088,7 @@ static void recalcData_objects(TransInfo *t)
     GSetIterator gs_iter;
     GSET_ITER (gs_iter, motionpath_updates) {
       Object *ob = BLI_gsetIterator_getKey(&gs_iter);
-      ED_pose_recalculate_paths(t->context, t->scene, ob, true);
+      ED_pose_recalculate_paths(t->context, t->scene, ob, POSE_PATH_CALC_RANGE_CURRENT_FRAME);
     }
     BLI_gset_free(motionpath_updates, NULL);
   }
@@ -1146,7 +1146,7 @@ static void recalcData_objects(TransInfo *t)
 
     if (motionpath_update) {
       /* Update motion paths once for all transformed objects. */
-      ED_objects_recalculate_paths(t->context, t->scene, true);
+      ED_objects_recalculate_paths(t->context, t->scene, OBJECT_PATH_CALC_RANGE_CHANGED);
     }
 
     if (t->options & CTX_OBMODE_XFORM_SKIP_CHILDREN) {