diff options
author | Joshua Leung <aligorith@gmail.com> | 2016-02-25 15:07:26 +0300 |
---|---|---|
committer | Joshua Leung <aligorith@gmail.com> | 2016-02-26 09:12:43 +0300 |
commit | 7dc419c8feb78dd1a4dad576a984932f81238dcd (patch) | |
tree | 51e98963542430454dcc3cf123a75f330bd5dc99 | |
parent | 0b1398930737ec4475706922809d1b88c18ac8fe (diff) |
Restore ability to clear motionpaths from selected objects/bones only
In response to user feedback, this commit brings back the ability to
limit motionpath clearing to only happening for those on selected
objects/bones.
By default, the "Clear" operator will clear from all objects/bones,
unless the Shift key is held.
-rw-r--r-- | source/blender/editors/armature/pose_edit.c | 41 | ||||
-rw-r--r-- | source/blender/editors/include/ED_object.h | 2 | ||||
-rw-r--r-- | source/blender/editors/object/object_edit.c | 59 |
3 files changed, 78 insertions, 24 deletions
diff --git a/source/blender/editors/armature/pose_edit.c b/source/blender/editors/armature/pose_edit.c index ef628208632..a929507929f 100644 --- a/source/blender/editors/armature/pose_edit.c +++ b/source/blender/editors/armature/pose_edit.c @@ -308,38 +308,44 @@ void POSE_OT_paths_update(wmOperatorType *ot) /* --------- */ /* for the object with pose/action: clear path curves for selected bones only */ -static void ED_pose_clear_paths(Object *ob) +static void ED_pose_clear_paths(Object *ob, bool only_selected) { bPoseChannel *pchan; - + bool skipped = false; + if (ELEM(NULL, ob, ob->pose)) return; /* free the motionpath blocks for all bones - This is easier for users to quickly clear all */ for (pchan = ob->pose->chanbase.first; pchan; pchan = pchan->next) { if (pchan->mpath) { - if (pchan->bone) { + if ((only_selected == false) || ((pchan->bone) && (pchan->bone->flag & BONE_SELECTED))) { animviz_free_motionpath(pchan->mpath); pchan->mpath = NULL; } + else { + skipped = true; + } } } - /* no paths left!*/ - ob->pose->avs.path_bakeflag &= ~MOTIONPATH_BAKE_HAS_PATHS; + /* if nothing was skipped, there should be no paths left! */ + if (skipped == false) + ob->pose->avs.path_bakeflag &= ~MOTIONPATH_BAKE_HAS_PATHS; } -/* operator callback for this */ -static int pose_clear_paths_exec(bContext *C, wmOperator *UNUSED(op)) +/* operator callback - wrapper for the backend function */ +static int pose_clear_paths_exec(bContext *C, wmOperator *op) { Object *ob = BKE_object_pose_armature_get(CTX_data_active_object(C)); - + bool only_selected = RNA_boolean_get(op->ptr, "only_selected"); + /* only continue if there's an object */ if (ELEM(NULL, ob, ob->pose)) return OPERATOR_CANCELLED; /* use the backend function for this */ - ED_pose_clear_paths(ob); + ED_pose_clear_paths(ob, only_selected); /* notifiers for updates */ WM_event_add_notifier(C, NC_OBJECT | ND_POSE, ob); @@ -347,19 +353,34 @@ static int pose_clear_paths_exec(bContext *C, wmOperator *UNUSED(op)) return OPERATOR_FINISHED; } +/* operator callback/wrapper */ +static int pose_clear_paths_invoke(bContext *C, wmOperator *op, const wmEvent *evt) +{ + if ((evt->shift) && !RNA_struct_property_is_set(op->ptr, "only_selected")) { + RNA_boolean_set(op->ptr, "only_selected", true); + } + return pose_clear_paths_exec(C, op); +} + void POSE_OT_paths_clear(wmOperatorType *ot) { /* identifiers */ ot->name = "Clear Bone Paths"; ot->idname = "POSE_OT_paths_clear"; - ot->description = "Clear path caches for all bones"; + ot->description = "Clear path caches for all bones, hold Shift key for selected bones only"; /* api callbacks */ + ot->invoke = pose_clear_paths_invoke; ot->exec = pose_clear_paths_exec; ot->poll = ED_operator_posemode_exclusive; /* flags */ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; + + /* properties */ + ot->prop = RNA_def_boolean(ot->srna, "only_selected", false, "Only Selected", + "Only clear paths from selected bones"); + RNA_def_property_flag(ot->prop, PROP_SKIP_SAVE); } /* ********************************************** */ diff --git a/source/blender/editors/include/ED_object.h b/source/blender/editors/include/ED_object.h index c9b7875aef0..04ff5692717 100644 --- a/source/blender/editors/include/ED_object.h +++ b/source/blender/editors/include/ED_object.h @@ -152,7 +152,7 @@ void ED_object_single_users(struct Main *bmain, struct Scene *scene, const bool void ED_object_single_user(struct Main *bmain, struct Scene *scene, struct Object *ob); /* object motion paths */ -void ED_objects_clear_paths(struct bContext *C); +void ED_objects_clear_paths(struct bContext *C, bool only_selected); void ED_objects_recalculate_paths(struct bContext *C, struct Scene *scene); /* constraints */ diff --git a/source/blender/editors/object/object_edit.c b/source/blender/editors/object/object_edit.c index 176d75c39ff..e8936e1f571 100644 --- a/source/blender/editors/object/object_edit.c +++ b/source/blender/editors/object/object_edit.c @@ -1324,26 +1324,44 @@ void OBJECT_OT_paths_update(wmOperatorType *ot) /* --------- */ +/* Helper for ED_objects_clear_paths() */ +static void object_clear_mpath(Object *ob) +{ + if (ob->mpath) { + animviz_free_motionpath(ob->mpath); + ob->mpath = NULL; + ob->avs.path_bakeflag &= ~MOTIONPATH_BAKE_HAS_PATHS; + } +} + /* Clear motion paths for all objects */ -void ED_objects_clear_paths(bContext *C) +void ED_objects_clear_paths(bContext *C, bool only_selected) { - /* loop over all edtiable objects in scene */ - CTX_DATA_BEGIN(C, Object *, ob, editable_objects) - { - if (ob->mpath) { - animviz_free_motionpath(ob->mpath); - ob->mpath = NULL; - ob->avs.path_bakeflag &= ~MOTIONPATH_BAKE_HAS_PATHS; + if (only_selected) { + /* loop over all selected + sedtiable objects in scene */ + CTX_DATA_BEGIN(C, Object *, ob, selected_editable_objects) + { + object_clear_mpath(ob); } + CTX_DATA_END; + } + else { + /* loop over all edtiable objects in scene */ + CTX_DATA_BEGIN(C, Object *, ob, editable_objects) + { + object_clear_mpath(ob); + } + CTX_DATA_END; } - CTX_DATA_END; } /* operator callback for this */ -static int object_clear_paths_exec(bContext *C, wmOperator *UNUSED(op)) -{ +static int object_clear_paths_exec(bContext *C, wmOperator *op) +{ + bool only_selected = RNA_boolean_get(op->ptr, "only_selected"); + /* use the backend function for this */ - ED_objects_clear_paths(C); + ED_objects_clear_paths(C, only_selected); /* notifiers for updates */ WM_event_add_notifier(C, NC_OBJECT | ND_TRANSFORM, NULL); @@ -1351,19 +1369,34 @@ static int object_clear_paths_exec(bContext *C, wmOperator *UNUSED(op)) return OPERATOR_FINISHED; } +/* operator callback/wrapper */ +static int object_clear_paths_invoke(bContext *C, wmOperator *op, const wmEvent *evt) +{ + if ((evt->shift) && !RNA_struct_property_is_set(op->ptr, "only_selected")) { + RNA_boolean_set(op->ptr, "only_selected", true); + } + return object_clear_paths_exec(C, op); +} + void OBJECT_OT_paths_clear(wmOperatorType *ot) { /* identifiers */ ot->name = "Clear Object Paths"; ot->idname = "OBJECT_OT_paths_clear"; - ot->description = "Clear path caches for all objects"; + ot->description = "Clear path caches for all objects, hold Shift key for selected objects only"; /* api callbacks */ + ot->invoke = object_clear_paths_invoke; ot->exec = object_clear_paths_exec; ot->poll = ED_operator_object_active_editable; /* flags */ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; + + /* properties */ + ot->prop = RNA_def_boolean(ot->srna, "only_selected", false, "Only Selected", + "Only clear paths from selected objects"); + RNA_def_property_flag(ot->prop, PROP_SKIP_SAVE); } |