mirror of
https://github.com/blender/blender
synced 2026-09-29 04:37:17 +03:00
Anim: Add F-Modifier Remove Operator
Add an operator to remove F-Curve modifiers, either all or limited by a few criteria. By default, all are removed. The 'Adjust Last Operation' (Redo) panel can be used to choose differently. - **All**: remove all the f-modifiers - **First**: only remove the first f-modifier - **Type**: the user can specify what type they want to remove, and all of those types are removed. Pull Request: https://projects.blender.org/blender/blender/pulls/156847
This commit is contained in:
parent
74a1a8fad1
commit
15a975ea3c
5 changed files with 149 additions and 1 deletions
|
|
@ -909,6 +909,7 @@ class DOPESHEET_MT_channel_context_menu(Menu):
|
|||
|
||||
if is_graph_editor:
|
||||
layout.operator_menu_enum("graph.fmodifier_add", "type", text="Add F-Curve Modifier").only_active = False
|
||||
layout.operator("graph.fmodifier_delete", text="Delete F-Curve Modifiers")
|
||||
layout.separator()
|
||||
layout.operator("graph.hide", text="Hide Selected Curves").unselected = False
|
||||
layout.operator("graph.hide", text="Hide Unselected Curves").unselected = True
|
||||
|
|
|
|||
|
|
@ -353,7 +353,7 @@ class GRAPH_MT_channel(Menu):
|
|||
# To get it to display the hotkey.
|
||||
layout.operator_context = operator_context
|
||||
layout.operator_menu_enum("graph.fmodifier_add", "type").only_active = False
|
||||
layout.operator_context = 'INVOKE_REGION_CHANNELS'
|
||||
layout.operator("graph.fmodifier_delete", text="Delete F-Curve Modifiers")
|
||||
|
||||
layout.separator()
|
||||
layout.operator("graph.hide", text="Hide Selected Curves").unselected = False
|
||||
|
|
|
|||
|
|
@ -58,6 +58,9 @@
|
|||
#include "ED_screen.hh"
|
||||
#include "ED_transform.hh"
|
||||
|
||||
#include "UI_interface_layout.hh"
|
||||
#include "UI_resources.hh"
|
||||
|
||||
#include "WM_api.hh"
|
||||
#include "WM_types.hh"
|
||||
|
||||
|
|
@ -2951,6 +2954,148 @@ void GRAPH_OT_fmodifier_add(wmOperatorType *ot)
|
|||
ot->srna, "only_active", false, "Only Active", "Only add F-Modifier to active F-Curve");
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name Delete F-Modifiers Operator
|
||||
* \{ */
|
||||
|
||||
enum class RemovalMode { ALL = 0, FIRST = 1, TYPE = 2 };
|
||||
|
||||
static wmOperatorStatus graph_fmodifier_delete_exec(bContext *C, wmOperator *op)
|
||||
{
|
||||
bAnimContext ac;
|
||||
ListBaseT<bAnimListElem> anim_data = {nullptr, nullptr};
|
||||
|
||||
const eFModifier_Types type = static_cast<eFModifier_Types>(RNA_enum_get(op->ptr, "type"));
|
||||
|
||||
/* Get editor data. */
|
||||
if (ANIM_animdata_get_context(C, &ac) == 0) {
|
||||
return OPERATOR_CANCELLED;
|
||||
}
|
||||
|
||||
/* Filter data. */
|
||||
eAnimFilter_Flags filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_FOREDIT | ANIMFILTER_NODUPLIS |
|
||||
ANIMFILTER_FCURVESONLY | ANIMFILTER_SEL | ANIMFILTER_CURVE_VISIBLE);
|
||||
|
||||
ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, ac.datatype);
|
||||
|
||||
const RemovalMode mode = RemovalMode(RNA_enum_get(op->ptr, "mode"));
|
||||
int num_fmods_deleted = 0;
|
||||
int num_fcurves_affected = 0;
|
||||
|
||||
/* Collect the F-Mods to delete. */
|
||||
for (bAnimListElem &ale : anim_data) {
|
||||
FCurve *fcu = static_cast<FCurve *>(ale.data);
|
||||
|
||||
/* Keep track of the modifiers to delete, so that we don't delete
|
||||
* them while looping over them. */
|
||||
Vector<FModifier *> fmods_to_delete;
|
||||
|
||||
for (FModifier &fcm : fcu->modifiers) {
|
||||
if (mode == RemovalMode::ALL || (mode == RemovalMode::TYPE && fcm.type == type)) {
|
||||
fmods_to_delete.append(&fcm);
|
||||
}
|
||||
}
|
||||
|
||||
if (mode == RemovalMode::FIRST) {
|
||||
if (FModifier *first = static_cast<FModifier *>(fcu->modifiers.first)) {
|
||||
fmods_to_delete.append(first);
|
||||
}
|
||||
}
|
||||
|
||||
/* Delete the modifiers. */
|
||||
for (FModifier *fmod : fmods_to_delete) {
|
||||
remove_fmodifier(&fcu->modifiers, fmod);
|
||||
num_fmods_deleted++;
|
||||
}
|
||||
|
||||
if (!fmods_to_delete.is_empty()) {
|
||||
num_fcurves_affected++;
|
||||
}
|
||||
|
||||
ale.update |= ANIM_UPDATE_DEPS;
|
||||
}
|
||||
|
||||
ANIM_animdata_update(&ac, &anim_data);
|
||||
ANIM_animdata_freelist(&anim_data);
|
||||
|
||||
/* Set notifier that things have changed. */
|
||||
WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_EDITED, nullptr);
|
||||
|
||||
if (num_fmods_deleted == 0) {
|
||||
BKE_report(op->reports, RPT_INFO, "No F-Modifiers found to delete");
|
||||
}
|
||||
else {
|
||||
BKE_reportf(op->reports,
|
||||
RPT_INFO,
|
||||
"Removed %d F-Modifier(s) from %d selected F-Curve(s)",
|
||||
num_fmods_deleted,
|
||||
num_fcurves_affected);
|
||||
}
|
||||
|
||||
return OPERATOR_FINISHED;
|
||||
}
|
||||
|
||||
static void fmodifier_delete_ui(bContext * /*C*/, wmOperator *op)
|
||||
{
|
||||
ui::Layout &layout = *op->layout;
|
||||
layout.use_property_split_set(true);
|
||||
|
||||
layout.prop(op->ptr, "mode", UI_ITEM_NONE, std::nullopt, ICON_NONE);
|
||||
if (RNA_enum_get(op->ptr, "mode") == int(RemovalMode::TYPE)) {
|
||||
layout.prop(op->ptr, "type", UI_ITEM_NONE, std::nullopt, ICON_NONE);
|
||||
}
|
||||
}
|
||||
|
||||
void GRAPH_OT_fmodifier_delete(wmOperatorType *ot)
|
||||
{
|
||||
PropertyRNA *prop;
|
||||
|
||||
/* Identifiers */
|
||||
ot->name = "Delete F-Curve Modifiers";
|
||||
ot->idname = "GRAPH_OT_fmodifier_delete";
|
||||
ot->description = "Remove Modifier(s) from the selected F-Curves";
|
||||
|
||||
/* API callbacks */
|
||||
ot->exec = graph_fmodifier_delete_exec;
|
||||
ot->ui = fmodifier_delete_ui;
|
||||
ot->poll = graphop_selected_fcurve_poll;
|
||||
|
||||
/* Flags */
|
||||
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
|
||||
|
||||
/* Id-props */
|
||||
static const EnumPropertyItem mode_items[] = {
|
||||
{int(RemovalMode::ALL),
|
||||
"ALL",
|
||||
0,
|
||||
"Remove All",
|
||||
"Remove all modifiers from the selected F-Curves"},
|
||||
{int(RemovalMode::FIRST),
|
||||
"FIRST",
|
||||
0,
|
||||
"Remove First",
|
||||
"Only remove the first modifier from each F-Curve regardless of type"},
|
||||
{int(RemovalMode::TYPE),
|
||||
"TYPE",
|
||||
0,
|
||||
"Remove Type",
|
||||
"Only remove the specified type of F-Curve modifier"},
|
||||
{0, nullptr, 0, nullptr, nullptr}};
|
||||
|
||||
RNA_def_enum(ot->srna,
|
||||
"mode",
|
||||
mode_items,
|
||||
int(RemovalMode::ALL),
|
||||
"Mode",
|
||||
"Decide what the operator will remove");
|
||||
|
||||
prop = RNA_def_enum(
|
||||
ot->srna, "type", rna_enum_fmodifier_type_items, FMODIFIER_TYPE_GENERATOR, "Type", "");
|
||||
RNA_def_property_translation_context(prop, BLT_I18NCONTEXT_ID_ACTION);
|
||||
RNA_def_enum_funcs(prop, graph_fmodifier_itemf);
|
||||
ot->prop = prop;
|
||||
}
|
||||
|
||||
/** \} */
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
|
|
|
|||
|
|
@ -192,6 +192,7 @@ enum eGraphKeys_Mirror_Mode {
|
|||
/* ----------- */
|
||||
|
||||
void GRAPH_OT_fmodifier_add(wmOperatorType *ot);
|
||||
void GRAPH_OT_fmodifier_delete(wmOperatorType *ot);
|
||||
void GRAPH_OT_fmodifier_copy(wmOperatorType *ot);
|
||||
void GRAPH_OT_fmodifier_paste(wmOperatorType *ot);
|
||||
|
||||
|
|
|
|||
|
|
@ -498,6 +498,7 @@ void graphedit_operatortypes()
|
|||
|
||||
/* F-Curve Modifiers */
|
||||
WM_operatortype_append(GRAPH_OT_fmodifier_add);
|
||||
WM_operatortype_append(GRAPH_OT_fmodifier_delete);
|
||||
WM_operatortype_append(GRAPH_OT_fmodifier_copy);
|
||||
WM_operatortype_append(GRAPH_OT_fmodifier_paste);
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue