Fix #87160: Clean Keyframes only works if channels are selected
The issue was that the code filtered for selected channels, while the expectation was that it would only filter for selected keys. This PR changes the behavior of the operator in the following way: * when "Clean Channels" is **disabled**, it will clean only selected keyframes, regardless of the channel selection * when "Clean Channels" is **enabled**, it will clean selected channels regardless of keyframe selection The same logic was applied to the Graph Editor code. It only makes a difference in the case when "Clean Channels" is enabled. That is because channels were automatically selected when a key was selected. In addition to that I moved the menu entry for "Clean Channels" to the channel menu to reduce confusion. Another solution would have been to make the Dope Sheet select channels when keys are selected. This might still be done in the future, but I think the only correct fix is to change the actual operator behavior. Pull Request: https://projects.blender.org/blender/blender/pulls/113335
This commit is contained in:
parent
8d15783a7e
commit
d85e7f4577
|
@ -495,6 +495,7 @@ class DOPESHEET_MT_channel(Menu):
|
||||||
layout.operator_context = 'INVOKE_REGION_CHANNELS'
|
layout.operator_context = 'INVOKE_REGION_CHANNELS'
|
||||||
|
|
||||||
layout.operator("anim.channels_delete")
|
layout.operator("anim.channels_delete")
|
||||||
|
layout.operator("action.clean", text="Clean Channels").channels = True
|
||||||
|
|
||||||
layout.separator()
|
layout.separator()
|
||||||
layout.operator("anim.channels_group")
|
layout.operator("anim.channels_group")
|
||||||
|
@ -555,7 +556,6 @@ class DOPESHEET_MT_key(Menu):
|
||||||
|
|
||||||
layout.separator()
|
layout.separator()
|
||||||
layout.operator("action.clean").channels = False
|
layout.operator("action.clean").channels = False
|
||||||
layout.operator("action.clean", text="Clean Channels").channels = True
|
|
||||||
layout.operator("action.bake_keys")
|
layout.operator("action.bake_keys")
|
||||||
|
|
||||||
layout.separator()
|
layout.separator()
|
||||||
|
|
|
@ -91,7 +91,11 @@ bool duplicate_fcurve_keys(FCurve *fcu)
|
||||||
/** \name Various Tools
|
/** \name Various Tools
|
||||||
* \{ */
|
* \{ */
|
||||||
|
|
||||||
void clean_fcurve(bAnimContext *ac, bAnimListElem *ale, float thresh, bool cleardefault)
|
void clean_fcurve(bAnimContext *ac,
|
||||||
|
bAnimListElem *ale,
|
||||||
|
float thresh,
|
||||||
|
bool cleardefault,
|
||||||
|
const bool only_selected_keys)
|
||||||
{
|
{
|
||||||
FCurve *fcu = (FCurve *)ale->key_data;
|
FCurve *fcu = (FCurve *)ale->key_data;
|
||||||
BezTriple *old_bezts, *bezt, *beztn;
|
BezTriple *old_bezts, *bezt, *beztn;
|
||||||
|
@ -144,7 +148,7 @@ void clean_fcurve(bAnimContext *ac, bAnimListElem *ale, float thresh, bool clear
|
||||||
cur[0] = bezt->vec[1][0];
|
cur[0] = bezt->vec[1][0];
|
||||||
cur[1] = bezt->vec[1][1];
|
cur[1] = bezt->vec[1][1];
|
||||||
|
|
||||||
if (!(bezt->f2 & SELECT)) {
|
if (only_selected_keys && !(bezt->f2 & SELECT)) {
|
||||||
insert_bezt_fcurve(fcu, bezt, eInsertKeyFlags(0));
|
insert_bezt_fcurve(fcu, bezt, eInsertKeyFlags(0));
|
||||||
lastb = (fcu->bezt + (fcu->totvert - 1));
|
lastb = (fcu->bezt + (fcu->totvert - 1));
|
||||||
lastb->f1 = lastb->f2 = lastb->f3 = 0;
|
lastb->f1 = lastb->f2 = lastb->f3 = 0;
|
||||||
|
|
|
@ -427,7 +427,11 @@ struct FCurveSegment {
|
||||||
* The caller is responsible for freeing the memory.
|
* The caller is responsible for freeing the memory.
|
||||||
*/
|
*/
|
||||||
ListBase find_fcurve_segments(FCurve *fcu);
|
ListBase find_fcurve_segments(FCurve *fcu);
|
||||||
void clean_fcurve(bAnimContext *ac, bAnimListElem *ale, float thresh, bool cleardefault);
|
void clean_fcurve(bAnimContext *ac,
|
||||||
|
bAnimListElem *ale,
|
||||||
|
float thresh,
|
||||||
|
bool cleardefault,
|
||||||
|
bool only_selected_keys);
|
||||||
void blend_to_neighbor_fcurve_segment(FCurve *fcu, FCurveSegment *segment, float factor);
|
void blend_to_neighbor_fcurve_segment(FCurve *fcu, FCurveSegment *segment, float factor);
|
||||||
void breakdown_fcurve_segment(FCurve *fcu, FCurveSegment *segment, float factor);
|
void breakdown_fcurve_segment(FCurve *fcu, FCurveSegment *segment, float factor);
|
||||||
void scale_average_fcurve_segment(struct FCurve *fcu, struct FCurveSegment *segment, float factor);
|
void scale_average_fcurve_segment(struct FCurve *fcu, struct FCurveSegment *segment, float factor);
|
||||||
|
|
|
@ -1182,12 +1182,18 @@ static void clean_action_keys(bAnimContext *ac, float thresh, bool clean_chan)
|
||||||
|
|
||||||
/* filter data */
|
/* filter data */
|
||||||
filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_FOREDIT |
|
filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_FOREDIT |
|
||||||
ANIMFILTER_SEL | ANIMFILTER_FCURVESONLY | ANIMFILTER_NODUPLIS);
|
ANIMFILTER_FCURVESONLY | ANIMFILTER_NODUPLIS);
|
||||||
|
|
||||||
|
if (clean_chan) {
|
||||||
|
filter |= ANIMFILTER_SEL;
|
||||||
|
}
|
||||||
|
|
||||||
ANIM_animdata_filter(ac, &anim_data, filter, ac->data, eAnimCont_Types(ac->datatype));
|
ANIM_animdata_filter(ac, &anim_data, filter, ac->data, eAnimCont_Types(ac->datatype));
|
||||||
|
|
||||||
|
const bool only_selected_keys = !clean_chan;
|
||||||
/* loop through filtered data and clean curves */
|
/* loop through filtered data and clean curves */
|
||||||
LISTBASE_FOREACH (bAnimListElem *, ale, &anim_data) {
|
LISTBASE_FOREACH (bAnimListElem *, ale, &anim_data) {
|
||||||
clean_fcurve(ac, ale, thresh, clean_chan);
|
clean_fcurve(ac, ale, thresh, clean_chan, only_selected_keys);
|
||||||
|
|
||||||
ale->update |= ANIM_UPDATE_DEFAULT;
|
ale->update |= ANIM_UPDATE_DEFAULT;
|
||||||
}
|
}
|
||||||
|
|
|
@ -830,13 +830,18 @@ static void clean_graph_keys(bAnimContext *ac, float thresh, bool clean_chan)
|
||||||
|
|
||||||
/* Filter data. */
|
/* Filter data. */
|
||||||
filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_CURVE_VISIBLE | ANIMFILTER_FCURVESONLY |
|
filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_CURVE_VISIBLE | ANIMFILTER_FCURVESONLY |
|
||||||
ANIMFILTER_FOREDIT | ANIMFILTER_SEL | ANIMFILTER_NODUPLIS);
|
ANIMFILTER_FOREDIT | ANIMFILTER_NODUPLIS);
|
||||||
|
if (clean_chan) {
|
||||||
|
filter |= ANIMFILTER_SEL;
|
||||||
|
}
|
||||||
ANIM_animdata_filter(
|
ANIM_animdata_filter(
|
||||||
ac, &anim_data, eAnimFilter_Flags(filter), ac->data, eAnimCont_Types(ac->datatype));
|
ac, &anim_data, eAnimFilter_Flags(filter), ac->data, eAnimCont_Types(ac->datatype));
|
||||||
|
|
||||||
|
const bool only_selected_keys = !clean_chan;
|
||||||
/* Loop through filtered data and clean curves. */
|
/* Loop through filtered data and clean curves. */
|
||||||
LISTBASE_FOREACH (bAnimListElem *, ale, &anim_data) {
|
LISTBASE_FOREACH (bAnimListElem *, ale, &anim_data) {
|
||||||
clean_fcurve(ac, ale, thresh, clean_chan);
|
|
||||||
|
clean_fcurve(ac, ale, thresh, clean_chan, only_selected_keys);
|
||||||
|
|
||||||
ale->update |= ANIM_UPDATE_DEFAULT;
|
ale->update |= ANIM_UPDATE_DEFAULT;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue