[Bf-blender-cvs] [615d5fa2fbd] master: Motion paths: Use minimal possible dependency graph

Sergey Sharybin noreply at git.blender.org
Wed Sep 25 14:42:12 CEST 2019


Commit: 615d5fa2fbd24ed6f76a93d7b523066f53da950e
Author: Sergey Sharybin
Date:   Fri Sep 20 17:38:32 2019 +0200
Branches: master
https://developer.blender.org/rB615d5fa2fbd24ed6f76a93d7b523066f53da950e

Motion paths: Use minimal possible dependency graph

This change makes it so motion paths are using minimal possible
dependency graph which is sufficient to evaluate required motion
path targets.

Disclaimer: granularity is done on ID level, but it is possible
to go more granular if really needed.

Brings time down to 0.5 sec when updating motion path for the
Rain animation file used for benchmarks in the previous commits.

Reviewers: brecht

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

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

M	source/blender/editors/animation/anim_motion_paths.c
M	source/blender/editors/armature/pose_edit.c
M	source/blender/editors/include/ED_anim_api.h
M	source/blender/editors/object/object_edit.c

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

diff --git a/source/blender/editors/animation/anim_motion_paths.c b/source/blender/editors/animation/anim_motion_paths.c
index aff532f4d54..30bf837f6c0 100644
--- a/source/blender/editors/animation/anim_motion_paths.c
+++ b/source/blender/editors/animation/anim_motion_paths.c
@@ -36,6 +36,7 @@
 #include "BKE_scene.h"
 
 #include "DEG_depsgraph.h"
+#include "DEG_depsgraph_build.h"
 #include "DEG_depsgraph_query.h"
 
 #include "GPU_batch.h"
@@ -67,6 +68,37 @@ typedef struct MPathTarget {
 
 /* ........ */
 
+/* update scene for current frame */
+static void motionpaths_calc_update_scene(Main *bmain, struct Depsgraph *depsgraph)
+{
+  BKE_scene_graph_update_for_newframe(depsgraph, bmain);
+}
+
+Depsgraph *animviz_depsgraph_build(Main *bmain,
+                                   Scene *scene,
+                                   ViewLayer *view_layer,
+                                   ListBase *targets)
+{
+  /* Allocate dependency graph. */
+  Depsgraph *depsgraph = DEG_graph_new(bmain, scene, view_layer, DAG_EVAL_VIEWPORT);
+
+  /* Make a flat array of IDs for the DEG API. */
+  const int num_ids = BLI_listbase_count(targets);
+  ID **ids = MEM_malloc_arrayN(sizeof(ID *), num_ids, "animviz IDS");
+  int current_id_index = 0;
+  for (MPathTarget *mpt = targets->first; mpt != NULL; mpt = mpt->next) {
+    ids[current_id_index++] = &mpt->ob->id;
+  }
+
+  /* Build graph from all requested IDs. */
+  DEG_graph_build_from_ids(depsgraph, bmain, scene, view_layer, ids, num_ids);
+  MEM_freeN(ids);
+
+  /* Update once so we can access pointers of evaluated animation data. */
+  motionpaths_calc_update_scene(bmain, depsgraph);
+  return depsgraph;
+}
+
 /* get list of motion paths to be baked for the given object
  * - assumes the given list is ready to be used
  */
@@ -106,24 +138,6 @@ void animviz_get_object_motionpaths(Object *ob, ListBase *targets)
 
 /* ........ */
 
-/* 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)
 {
diff --git a/source/blender/editors/armature/pose_edit.c b/source/blender/editors/armature/pose_edit.c
index e2c9828c20f..ad115896a43 100644
--- a/source/blender/editors/armature/pose_edit.c
+++ b/source/blender/editors/armature/pose_edit.c
@@ -208,12 +208,12 @@ void ED_pose_recalculate_paths(bContext *C, Scene *scene, Object *ob, ePosePathC
   }
 
   Main *bmain = CTX_data_main(C);
-  /* NOTE: Dependency graph will be evaluated at all the frames, but we first need to access some
-   * nested pointers, like animation data. */
-  Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(C);
-  ListBase targets = {NULL, NULL};
+  ViewLayer *view_layer = CTX_data_view_layer(C);
+
+  Depsgraph *depsgraph;
   bool free_depsgraph = false;
 
+  ListBase targets = {NULL, NULL};
   /* set flag to force recalc, then grab the relevant bones to target */
   ob->pose->avs.recalc |= ANIMVIZ_RECALC_PATHS;
   animviz_get_object_motionpaths(ob, &targets);
@@ -223,6 +223,19 @@ void ED_pose_recalculate_paths(bContext *C, Scene *scene, Object *ob, ePosePathC
   TIMEIT_START(pose_path_calc);
 #endif
 
+  /* For a single frame update it's faster to re-use existing dependency graph and avoid overhead
+   * of building all the relations and so on for a temporary one.  */
+  if (range == POSE_PATH_CALC_RANGE_CURRENT_FRAME) {
+    /* NOTE: Dependency graph will be evaluated at all the frames, but we first need to access some
+     * nested pointers, like animation data. */
+    depsgraph = CTX_data_ensure_evaluated_depsgraph(C);
+    free_depsgraph = false;
+  }
+  else {
+    depsgraph = animviz_depsgraph_build(bmain, scene, view_layer, &targets);
+    free_depsgraph = true;
+  }
+
   animviz_calc_motionpaths(
       depsgraph, bmain, scene, &targets, pose_path_convert_range(range), !free_depsgraph);
 
@@ -238,7 +251,7 @@ void ED_pose_recalculate_paths(bContext *C, Scene *scene, Object *ob, ePosePathC
     DEG_id_tag_update(&ob->id, ID_RECALC_COPY_ON_WRITE);
   }
 
-  /* Free temporary depsgraph instance */
+  /* Free temporary depsgraph. */
   if (free_depsgraph) {
     DEG_graph_free(depsgraph);
   }
diff --git a/source/blender/editors/include/ED_anim_api.h b/source/blender/editors/include/ED_anim_api.h
index c262f390dc6..bf9b69f12e1 100644
--- a/source/blender/editors/include/ED_anim_api.h
+++ b/source/blender/editors/include/ED_anim_api.h
@@ -845,6 +845,11 @@ typedef enum eAnimvizCalcRange {
   ANIMVIZ_CALC_RANGE_FULL,
 } eAnimvizCalcRange;
 
+struct Depsgraph *animviz_depsgraph_build(struct Main *bmain,
+                                          struct Scene *scene,
+                                          struct ViewLayer *view_layer,
+                                          struct ListBase *targets);
+
 void animviz_calc_motionpaths(struct Depsgraph *depsgraph,
                               struct Main *bmain,
                               struct Scene *scene,
diff --git a/source/blender/editors/object/object_edit.c b/source/blender/editors/object/object_edit.c
index 77897c909d9..4759a3cb0db 100644
--- a/source/blender/editors/object/object_edit.c
+++ b/source/blender/editors/object/object_edit.c
@@ -936,11 +936,9 @@ void ED_objects_recalculate_paths(bContext *C, Scene *scene, eObjectPathCalcRang
   }
 
   Main *bmain = CTX_data_main(C);
-  /* NOTE: Dependency graph will be evaluated at all the frames, but we first need to access some
-   * nested pointers, like animation data. */
-  Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(C);
-  ListBase targets = {NULL, NULL};
+  ViewLayer *view_layer = CTX_data_view_layer(C);
 
+  ListBase targets = {NULL, NULL};
   /* loop over objects in scene */
   CTX_DATA_BEGIN (C, Object *, ob, selected_editable_objects) {
     /* set flag to force recalc, then grab path(s) from object */
@@ -949,6 +947,21 @@ void ED_objects_recalculate_paths(bContext *C, Scene *scene, eObjectPathCalcRang
   }
   CTX_DATA_END;
 
+  Depsgraph *depsgraph;
+  bool free_depsgraph = false;
+  /* For a single frame update it's faster to re-use existing dependency graph and avoid overhead
+   * of building all the relations and so on for a temporary one.  */
+  if (range == OBJECT_PATH_CALC_RANGE_CURRENT_FRAME) {
+    /* NOTE: Dependency graph will be evaluated at all the frames, but we first need to access some
+     * nested pointers, like animation data. */
+    depsgraph = CTX_data_ensure_evaluated_depsgraph(C);
+    free_depsgraph = false;
+  }
+  else {
+    depsgraph = animviz_depsgraph_build(bmain, scene, view_layer, &targets);
+    free_depsgraph = true;
+  }
+
   /* recalculate paths, then free */
   animviz_calc_motionpaths(
       depsgraph, bmain, scene, &targets, object_path_convert_range(range), true);
@@ -964,6 +977,11 @@ void ED_objects_recalculate_paths(bContext *C, Scene *scene, eObjectPathCalcRang
     }
     CTX_DATA_END;
   }
+
+  /* Free temporary depsgraph. */
+  if (free_depsgraph) {
+    DEG_graph_free(depsgraph);
+  }
 }
 
 /* show popup to determine settings */



More information about the Bf-blender-cvs mailing list