Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJan-Willem van Dronkelaar <jwvd>2021-10-18 15:23:23 +0300
committerSybren A. Stüvel <sybren@blender.org>2021-10-18 15:36:26 +0300
commit4de0e2e7717f458b496fdf2b00a724412abb88a0 (patch)
tree5663c5be55872ce24beb533fd0d8464000fa491e
parentf9113c4be836691ba599aab9b2f43e26333f8133 (diff)
Animation: Motion Paths Refresh All
Adds a button, Update All Paths, to the Motion Paths property tabs and will always show. The operator goes through all visible objects and updates their motion paths. The current implementation has a subtle functional change. Calculating or updating motion paths for armature objects (through the Object tab, not Armature tab) now also updates the paths for its bones. We could preserve the old behavior but it doesn't seem necessary. It seems more likely that the animator wants to update both anyways. Reviewed by: sybren Maniphest Tasks: T83068 Differential Revision: https://developer.blender.org/D11667
-rw-r--r--release/scripts/startup/bl_ui/properties_animviz.py7
-rw-r--r--release/scripts/startup/bl_ui/space_view3d.py2
-rw-r--r--source/blender/editors/include/ED_object.h11
-rw-r--r--source/blender/editors/object/object_edit.c114
-rw-r--r--source/blender/editors/object/object_intern.h1
-rw-r--r--source/blender/editors/object/object_ops.c1
-rw-r--r--source/blender/editors/transform/transform_convert_object.c5
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);