diff options
-rw-r--r-- | release/scripts/startup/bl_ui/properties_animviz.py | 7 | ||||
-rw-r--r-- | release/scripts/startup/bl_ui/space_view3d.py | 2 | ||||
-rw-r--r-- | source/blender/editors/include/ED_object.h | 11 | ||||
-rw-r--r-- | source/blender/editors/object/object_edit.c | 114 | ||||
-rw-r--r-- | source/blender/editors/object/object_intern.h | 1 | ||||
-rw-r--r-- | source/blender/editors/object/object_ops.c | 1 | ||||
-rw-r--r-- | source/blender/editors/transform/transform_convert_object.c | 5 |
7 files changed, 124 insertions, 17 deletions
diff --git a/release/scripts/startup/bl_ui/properties_animviz.py b/release/scripts/startup/bl_ui/properties_animviz.py index 6c3c1fd1721..92e78cd32b6 100644 --- a/release/scripts/startup/bl_ui/properties_animviz.py +++ b/release/scripts/startup/bl_ui/properties_animviz.py @@ -68,20 +68,25 @@ class MotionPathButtonsPanel: col.prop(mpath, "frame_start", text="Cache From") col.prop(mpath, "frame_end", text="To") - row = layout.row(align=True) + col = layout.column(align=True) + + row = col.row(align=True) if bones: row.operator("pose.paths_update", text="Update Paths", icon='BONE_DATA') row.operator("pose.paths_clear", text="", icon='X') else: row.operator("object.paths_update", text="Update Paths", icon='OBJECT_DATA') row.operator("object.paths_clear", text="", icon='X') + col.operator("object.paths_update_visible", text="Update All Paths", icon="WORLD") else: col = layout.column(align=True) col.label(text="Nothing to show yet...", icon='ERROR') + if bones: col.operator("pose.paths_calculate", text="Calculate...", icon='BONE_DATA') else: col.operator("object.paths_calculate", text="Calculate...", icon='OBJECT_DATA') + col.operator("object.paths_update_visible", text="Update All Paths", icon="WORLD") class MotionPathButtonsPanel_display: diff --git a/release/scripts/startup/bl_ui/space_view3d.py b/release/scripts/startup/bl_ui/space_view3d.py index 64652dc8ff8..1808287f7a9 100644 --- a/release/scripts/startup/bl_ui/space_view3d.py +++ b/release/scripts/startup/bl_ui/space_view3d.py @@ -3601,6 +3601,8 @@ class VIEW3D_MT_pose_context_menu(Menu): layout.operator("pose.paths_calculate", text="Calculate Motion Paths") layout.operator("pose.paths_clear", text="Clear Motion Paths") + layout.operator("pose.paths_update", text="Update Armature Motion Paths") + layout.operator("object.paths_update_visible", text="Update All Motion Paths") layout.separator() diff --git a/source/blender/editors/include/ED_object.h b/source/blender/editors/include/ED_object.h index 5397cd95ace..083d167c573 100644 --- a/source/blender/editors/include/ED_object.h +++ b/source/blender/editors/include/ED_object.h @@ -339,7 +339,16 @@ typedef enum eObjectPathCalcRange { void ED_objects_recalculate_paths(struct bContext *C, struct Scene *scene, - eObjectPathCalcRange range); + eObjectPathCalcRange range, + struct ListBase *ld_objects); + +void ED_objects_recalculate_paths_selected(struct bContext *C, + struct Scene *scene, + eObjectPathCalcRange range); + +void ED_objects_recalculate_paths_visible(struct bContext *C, + struct Scene *scene, + eObjectPathCalcRange 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 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 * \{ */ diff --git a/source/blender/editors/object/object_intern.h b/source/blender/editors/object/object_intern.h index d00e6efeb29..ea9a2de090b 100644 --- a/source/blender/editors/object/object_intern.h +++ b/source/blender/editors/object/object_intern.h @@ -84,6 +84,7 @@ void OBJECT_OT_paths_calculate(struct wmOperatorType *ot); void OBJECT_OT_paths_update(struct wmOperatorType *ot); void OBJECT_OT_paths_clear(struct wmOperatorType *ot); void OBJECT_OT_paths_range_update(struct wmOperatorType *ot); +void OBJECT_OT_paths_update_visible(struct wmOperatorType *ot); void OBJECT_OT_forcefield_toggle(struct wmOperatorType *ot); void OBJECT_OT_move_to_collection(struct wmOperatorType *ot); diff --git a/source/blender/editors/object/object_ops.c b/source/blender/editors/object/object_ops.c index fa0208a7022..b3bf2c64a91 100644 --- a/source/blender/editors/object/object_ops.c +++ b/source/blender/editors/object/object_ops.c @@ -62,6 +62,7 @@ void ED_operatortypes_object(void) WM_operatortype_append(OBJECT_OT_paths_update); WM_operatortype_append(OBJECT_OT_paths_clear); WM_operatortype_append(OBJECT_OT_paths_range_update); + WM_operatortype_append(OBJECT_OT_paths_update_visible); WM_operatortype_append(OBJECT_OT_forcefield_toggle); WM_operatortype_append(OBJECT_OT_transfer_mode); diff --git a/source/blender/editors/transform/transform_convert_object.c b/source/blender/editors/transform/transform_convert_object.c index 1acd8787f51..947fbb00fad 100644 --- a/source/blender/editors/transform/transform_convert_object.c +++ b/source/blender/editors/transform/transform_convert_object.c @@ -910,7 +910,8 @@ void recalcData_objects(TransInfo *t) if (motionpath_update) { /* Update motion paths once for all transformed objects. */ - ED_objects_recalculate_paths(t->context, t->scene, OBJECT_PATH_CALC_RANGE_CURRENT_FRAME); + ED_objects_recalculate_paths_selected( + t->context, t->scene, OBJECT_PATH_CALC_RANGE_CURRENT_FRAME); } if (t->options & CTX_OBMODE_XFORM_SKIP_CHILDREN) { @@ -994,7 +995,7 @@ void special_aftertrans_update__object(bContext *C, TransInfo *t) /* Update motion paths once for all transformed objects. */ const eObjectPathCalcRange range = canceled ? OBJECT_PATH_CALC_RANGE_CURRENT_FRAME : OBJECT_PATH_CALC_RANGE_CHANGED; - ED_objects_recalculate_paths(C, t->scene, range); + ED_objects_recalculate_paths_selected(C, t->scene, range); } clear_trans_object_base_flags(t); |