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.
This commit is contained in:
@@ -308,9 +308,10 @@ 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;
|
||||
@@ -318,28 +319,33 @@ static void ED_pose_clear_paths(Object *ob)
|
||||
/* 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!*/
|
||||
/* 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);
|
||||
}
|
||||
|
||||
/* ********************************************** */
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -1324,11 +1324,8 @@ void OBJECT_OT_paths_update(wmOperatorType *ot)
|
||||
|
||||
/* --------- */
|
||||
|
||||
/* Clear motion paths for all objects */
|
||||
void ED_objects_clear_paths(bContext *C)
|
||||
{
|
||||
/* loop over all edtiable objects in scene */
|
||||
CTX_DATA_BEGIN(C, Object *, ob, editable_objects)
|
||||
/* Helper for ED_objects_clear_paths() */
|
||||
static void object_clear_mpath(Object *ob)
|
||||
{
|
||||
if (ob->mpath) {
|
||||
animviz_free_motionpath(ob->mpath);
|
||||
@@ -1336,14 +1333,35 @@ void ED_objects_clear_paths(bContext *C)
|
||||
ob->avs.path_bakeflag &= ~MOTIONPATH_BAKE_HAS_PATHS;
|
||||
}
|
||||
}
|
||||
|
||||
/* Clear motion paths for all objects */
|
||||
void ED_objects_clear_paths(bContext *C, bool only_selected)
|
||||
{
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
/* 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);
|
||||
}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user