diff options
Diffstat (limited to 'source/blender/editors/object/object_edit.c')
-rw-r--r-- | source/blender/editors/object/object_edit.c | 114 |
1 files changed, 101 insertions, 13 deletions
diff --git a/source/blender/editors/object/object_edit.c b/source/blender/editors/object/object_edit.c index 2bd0ae5f121..78440f52160 100644 --- a/source/blender/editors/object/object_edit.c +++ b/source/blender/editors/object/object_edit.c @@ -1125,12 +1125,51 @@ static eAnimvizCalcRange object_path_convert_range(eObjectPathCalcRange range) return ANIMVIZ_CALC_RANGE_FULL; } +void ED_objects_recalculate_paths_selected(bContext *C, Scene *scene, eObjectPathCalcRange range) +{ + ListBase selected_objects = {NULL, NULL}; + CTX_DATA_BEGIN (C, Object *, ob, selected_editable_objects) { + BLI_addtail(&selected_objects, BLI_genericNodeN(ob)); + } + CTX_DATA_END; + + ED_objects_recalculate_paths(C, scene, range, &selected_objects); + + BLI_freelistN(&selected_objects); +} + +void ED_objects_recalculate_paths_visible(bContext *C, Scene *scene, eObjectPathCalcRange range) +{ + ListBase visible_objects = {NULL, NULL}; + CTX_DATA_BEGIN (C, Object *, ob, visible_objects) { + BLI_addtail(&visible_objects, BLI_genericNodeN(ob)); + } + CTX_DATA_END; + + ED_objects_recalculate_paths(C, scene, range, &visible_objects); + + BLI_freelistN(&visible_objects); +} + +static bool has_object_motion_paths(Object *ob) +{ + return (ob->avs.path_bakeflag & MOTIONPATH_BAKE_HAS_PATHS) != 0; +} + +static bool has_pose_motion_paths(Object *ob) +{ + return ob->pose && (ob->pose->avs.path_bakeflag & MOTIONPATH_BAKE_HAS_PATHS) != 0; +} + /* 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, eObjectPathCalcRange range) +void ED_objects_recalculate_paths(bContext *C, + Scene *scene, + eObjectPathCalcRange range, + ListBase *ld_objects) { /* Transform doesn't always have context available to do update. */ if (C == NULL) { @@ -1141,13 +1180,20 @@ void ED_objects_recalculate_paths(bContext *C, Scene *scene, eObjectPathCalcRang 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) { + LISTBASE_FOREACH (LinkData *, link, ld_objects) { + Object *ob = link->data; + /* set flag to force recalc, then grab path(s) from object */ - ob->avs.recalc |= ANIMVIZ_RECALC_PATHS; + if (has_object_motion_paths(ob)) { + ob->avs.recalc |= ANIMVIZ_RECALC_PATHS; + } + + if (has_pose_motion_paths(ob)) { + ob->pose->avs.recalc |= ANIMVIZ_RECALC_PATHS; + } + animviz_get_object_motionpaths(ob, &targets); } - CTX_DATA_END; Depsgraph *depsgraph; bool free_depsgraph = false; @@ -1172,12 +1218,13 @@ void ED_objects_recalculate_paths(bContext *C, Scene *scene, eObjectPathCalcRang 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) { - if (ob->mpath) { + LISTBASE_FOREACH (LinkData *, link, ld_objects) { + Object *ob = link->data; + + if (has_object_motion_paths(ob) || has_pose_motion_paths(ob)) { DEG_id_tag_update(&ob->id, ID_RECALC_COPY_ON_WRITE); } } - CTX_DATA_END; } /* Free temporary depsgraph. */ @@ -1229,10 +1276,10 @@ 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, OBJECT_PATH_CALC_RANGE_FULL); + ED_objects_recalculate_paths_selected(C, scene, OBJECT_PATH_CALC_RANGE_FULL); /* notifiers for updates */ - WM_event_add_notifier(C, NC_OBJECT | ND_TRANSFORM, NULL); + WM_event_add_notifier(C, NC_OBJECT | ND_TRANSFORM | ND_POSE, NULL); return OPERATOR_FINISHED; } @@ -1298,10 +1345,10 @@ 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, OBJECT_PATH_CALC_RANGE_FULL); + ED_objects_recalculate_paths_selected(C, scene, OBJECT_PATH_CALC_RANGE_FULL); /* notifiers for updates */ - WM_event_add_notifier(C, NC_OBJECT | ND_TRANSFORM, NULL); + WM_event_add_notifier(C, NC_OBJECT | ND_TRANSFORM | ND_POSE, NULL); return OPERATOR_FINISHED; } @@ -1311,7 +1358,7 @@ void OBJECT_OT_paths_update(wmOperatorType *ot) /* identifiers */ ot->name = "Update Object Paths"; ot->idname = "OBJECT_OT_paths_update"; - ot->description = "Recalculate paths for selected objects"; + ot->description = "Recalculate motion paths for selected objects"; /* api callbacks */ ot->exec = object_update_paths_exec; @@ -1324,6 +1371,47 @@ void OBJECT_OT_paths_update(wmOperatorType *ot) /** \} */ /* -------------------------------------------------------------------- */ +/** \name Update All Motion Paths Operator + * \{ */ + +static bool object_update_all_paths_poll(bContext *UNUSED(C)) +{ + return true; +} + +static int object_update_all_paths_exec(bContext *C, wmOperator *UNUSED(op)) +{ + Scene *scene = CTX_data_scene(C); + + if (scene == NULL) { + return OPERATOR_CANCELLED; + } + + ED_objects_recalculate_paths_visible(C, scene, OBJECT_PATH_CALC_RANGE_FULL); + + WM_event_add_notifier(C, NC_OBJECT | ND_POSE | ND_TRANSFORM, NULL); + + return OPERATOR_FINISHED; +} + +void OBJECT_OT_paths_update_visible(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Update All Object Paths"; + ot->idname = "OBJECT_OT_paths_update_visible"; + ot->description = "Recalculate all visible motion paths for objects and poses"; + + /* api callbacks */ + ot->exec = object_update_all_paths_exec; + ot->poll = object_update_all_paths_poll; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; +} + +/** \} */ + +/* -------------------------------------------------------------------- */ /** \name Clear Motion Paths Operator * \{ */ |