diff options
-rw-r--r-- | source/blender/editors/animation/anim_motion_paths.c | 50 | ||||
-rw-r--r-- | source/blender/editors/armature/pose_edit.c | 23 | ||||
-rw-r--r-- | source/blender/editors/include/ED_anim_api.h | 5 | ||||
-rw-r--r-- | source/blender/editors/object/object_edit.c | 26 |
4 files changed, 77 insertions, 27 deletions
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 */ |