12#include <fmt/format.h>
69#include "RNA_prototypes.hh"
86 int old_flag = fcu->
flag;
89 BKE_report(reports,
RPT_ERROR,
"No RNA pointer available to retrieve values for this F-curve");
100 "Could not update flags for this F-curve, as RNA path is invalid for the given ID "
101 "(ID = %s, path = %s)",
110 if (old_flag != fcu->
flag) {
120 BLI_assert_msg(num_keys_to_add >= 0,
"cannot remove keyframes with this function");
122 if (num_keys_to_add == 0) {
130 fcu->
totvert += num_keys_to_add;
133 while (num_keys_to_add--) {
162 if (
ELEM(
nullptr, area, scene)) {
176 bool ob_edit_mode =
false;
194 "Keying set '%s' - successfully added %d keyframes",
205 if (num_channels < 0) {
210 if (num_channels > 0) {
217 if (num_channels > 0) {
220 "Successfully added %d keyframes for keying set '%s'",
242 eIDPropertyType::IDP_BOOLEAN,
243 eIDPropertyType::IDP_INT,
244 eIDPropertyType::IDP_FLOAT,
245 eIDPropertyType::IDP_DOUBLE))
250 if (id_prop->
type == eIDPropertyType::IDP_ARRAY) {
252 eIDPropertyType::IDP_BOOLEAN,
253 eIDPropertyType::IDP_INT,
254 eIDPropertyType::IDP_FLOAT,
255 eIDPropertyType::IDP_DOUBLE))
270 if (
ptr->
type == &RNA_PoseBone) {
273 properties = pchan->
prop;
275 else if (
ptr->
type == &RNA_Object) {
287 paths.append({
"location"});
290 switch (rotation_mode) {
292 paths.append({
"rotation_quaternion"});
295 paths.append({
"rotation_axis_angle"});
303 paths.append({
"rotation_euler"});
309 paths.append({
"scale"});
312 paths.append({
"rotation_mode"});
319 std::string path = id_prop->
name;
325 ptr, path.c_str(), &resolved_ptr, &resolved_prop);
328 BLI_str_escape(name_escaped, id_prop->name,
sizeof(name_escaped));
329 path = fmt::format(
"[\"{}\"]", name_escaped);
331 ptr, path.c_str(), &resolved_ptr, &resolved_prop);
337 paths.append({path});
350 switch (context_mode) {
372 if (!found_selection) {
377 if (selection.is_empty()) {
386 const eInsertKeyFlags insert_key_flags = animrig::get_keyframing_flags(scene);
388 scene->toolsettings->keyframe_type);
396 ID *selected_id = id_ptr.owner_id;
397 ids.
add(selected_id);
401 "Could not insert keyframe, as this type does not support animation data (ID = "
412 combined_result.
merge(animrig::insert_keyframes(bmain,
422 if (combined_result.
get_count(animrig::SingleKeyingResult::SUCCESS) == 0) {
462 ot->
name =
"Insert Keyframe";
463 ot->
idname =
"ANIM_OT_keyframe_insert";
465 "Insert keyframes on the current frame using either the active keying set, or the user "
466 "preferences if no keying set is active";
501 ot->
name =
"Insert Keyframe (by name)";
502 ot->
idname =
"ANIM_OT_keyframe_insert_by_name";
503 ot->
description =
"Alternate access to 'Insert Keyframe' for keymaps to use";
514 ot->
srna,
"type",
nullptr,
MAX_ID_NAME - 2,
"Keying Set",
"The Keying Set to use");
556 for (
int i = 0; i < totitem; i++) {
562 "ANIM_OT_keyframe_insert_by_name",
589 ot->
name =
"Insert Keyframe Menu";
590 ot->
idname =
"ANIM_OT_keyframe_insert_menu";
592 "Insert Keyframes for specified Keying Set, with menu of available Keying Sets if undefined";
641 printf(
"KeyingSet '%s' - Successfully removed %d Keyframes\n", ks->
name, num_channels);
645 if (num_channels < 0) {
650 if (num_channels > 0) {
656 if (num_channels > 0) {
659 "Successfully removed %d keyframes for keying set '%s'",
675 ot->
name =
"Delete Keying-Set Keyframe";
676 ot->
idname =
"ANIM_OT_keyframe_delete";
678 "Delete keyframes on the current frame for all properties in the specified Keying Set";
700 ot->
name =
"Delete Keying-Set Keyframe (by name)";
701 ot->
idname =
"ANIM_OT_keyframe_delete_by_name";
702 ot->
description =
"Alternate access to 'Delete Keyframe' for keymaps to use";
713 ot->
srna,
"type",
nullptr,
MAX_ID_NAME - 2,
"Keying Set",
"The Keying Set to use");
728 bool can_delete =
false;
734 char bone_name[
sizeof(pchan->
name)];
738 if ((pchan) && (pchan->
bone)) {
759 bool changed =
false;
763 if ((ob->adt) && (ob->adt->action)) {
768 Action &action = dna_action->wrap();
772 if (can_delete_fcurve(&fcurve, ob)) {
773 fcurves_to_delete.append(&fcurve);
776 for (
FCurve *fcurve : fcurves_to_delete) {
777 action_fcurve_remove(action, *fcurve);
781 for (fcu =
static_cast<FCurve *
>(dna_action->curves.first); fcu; fcu = fcn) {
815 IFACE_(
"Remove animation from selected objects?"),
827 ot->
name =
"Remove Animation";
828 ot->
description =
"Remove all keyframe animation for selected objects";
829 ot->
idname =
"ANIM_OT_keyframe_clear_v3d";
848 "Not deleting keyframe for locked F-Curve '%s', object '%s'",
864 char bone_name[
sizeof(pchan->
name)];
871 if ((pchan) && (pchan->
bone)) {
900 int selected_objects_len = 0;
901 int selected_objects_success_len = 0;
902 int success_multi = 0;
909 selected_objects_len += 1;
912 if ((ob->adt) && (ob->adt->action)) {
917 Action &action = act->wrap();
921 if (!can_delete_key(&fcurve, ob, op->reports)) {
925 modified_fcurves.
append(&fcurve);
929 success += modified_fcurves.size();
930 for (
FCurve *fcurve : modified_fcurves) {
932 action_fcurve_remove(action, *fcurve);
938 for (
FCurve *fcu =
static_cast<FCurve *
>(act->curves.first); fcu; fcu = fcn) {
946 success += delete_keyframe_fcurve_legacy(adt, fcu, cfra_unmap);
950 if (ob->adt->action) {
959 selected_objects_success_len += 1;
960 success_multi += success;
967 if (selected_objects_success_len) {
974 if (selected_objects_success_len) {
977 "%d object(s) successfully had %d keyframes removed",
978 selected_objects_success_len,
983 op->reports,
RPT_ERROR,
"No keyframes removed from %d object(s)", selected_objects_len);
1006 IFACE_(
"Delete keyframes from selected objects?"),
1018 ot->
name =
"Delete Keyframe";
1019 ot->
description =
"Remove keyframes on current frame for selected objects and bones";
1020 ot->
idname =
"ANIM_OT_keyframe_delete_v3d";
1046 bool changed =
false;
1051 flag = get_keyframing_flags(scene);
1059 if (
ptr.
type == &RNA_NlaStrip) {
1068 changed = insert_keyframe_direct(op->
reports,
1080 "This property cannot be animated as it will not get updated correctly");
1086 bool driven, special;
1089 C, &
ptr, prop, index,
nullptr,
nullptr, &driven, &special);
1091 if (fcu && driven) {
1092 const float driver_frame = evaluate_driver_from_rna_pointer(
1093 &anim_eval_context, &
ptr, prop, fcu);
1096 changed = insert_keyframe_direct(op->
reports,
1110 const std::optional<blender::StringRefNull> group = default_channel_group_for_path(
1117 const std::optional<int> array_index = (all || index < 0) ? std::nullopt :
1118 std::optional(index);
1123 {{*path, {}, array_index}},
1128 changed = result.
get_count(SingleKeyingResult::SUCCESS) != 0;
1133 "Failed to resolve path to property, "
1134 "try manually specifying this using a Keying Set instead");
1142 "\"%s\" property cannot be animated",
1148 "Button doesn't appear to have any property information attached (ptr.data = "
1158 if (adt->
action !=
nullptr) {
1176 ot->
name =
"Insert Keyframe (Buttons)";
1177 ot->
idname =
"ANIM_OT_keyframe_insert_button";
1178 ot->
description =
"Insert a keyframe for current UI-active property";
1200 bool changed =
false;
1224 "Not deleting keyframe for locked F-Curve for NLA Strip influence on %s - %s '%s'",
1251 RNAPath rna_path = {path->c_str(), std::nullopt, index};
1254 rna_path.
index = std::nullopt;
1261 printf(
"Button Delete-Key: no path to property\n");
1266 printf(
"ptr.data = %p, prop = %p\n",
ptr.
data, (
void *)prop);
1283 ot->
name =
"Delete Keyframe (Buttons)";
1284 ot->
idname =
"ANIM_OT_keyframe_delete_button";
1285 ot->
description =
"Delete current keyframe of current UI-active property";
1305 bool changed =
false;
1316 RNAPath rna_path = {path->c_str(), std::nullopt, index};
1319 rna_path.
index = std::nullopt;
1326 printf(
"Button Clear-Key: no path to property\n");
1330 printf(
"ptr.data = %p, prop = %p\n",
ptr.
data, (
void *)prop);
1347 ot->
name =
"Clear Keyframe (Buttons)";
1348 ot->
idname =
"ANIM_OT_keyframe_clear_button";
1349 ot->
description =
"Clear all keyframes on the currently active property";
1370 if (
ELEM(
nullptr, fcu, fcu->
bezt)) {
1383 if ((i >= 0) && (i < fcu->totvert)) {
1399 anim_rna.
prop = prop;
1406 float cur_val = (index >= 0 && index < values.size()) ? values[index] : 0.0f;
1421 if (adt.
action ==
nullptr) {
1434 if (fcu->bezt && fcu->totvert) {
1449 if (ob ==
nullptr) {
1475 if (
id ==
nullptr) {
1480 switch (
GS(id->name)) {
1516 if (ks ==
nullptr) {
1524 if (
STREQ(type_id,
"__ACTIVE__")) {
1531 if (ks ==
nullptr) {
Functions and classes to work with Actions.
Functionality to iterate an Action in various ways.
Functions for backward compatibility with the legacy Action API.
Functions to work with AnimData.
C++ functions to deal with Armature collections (i.e. the successor of bone layers).
bool ANIM_bonecoll_is_visible_pchan(const bArmature *armature, const bPoseChannel *pchan)
Functions to work with drivers.
Functions to modify FCurves.
Functions to insert, delete or modify keyframes.
Functionality to interact with keying sets.
Helper functions for animation to interact with the RNA system.
Blender kernel action and pose functionality.
bPoseChannel * BKE_pose_channel_find_name(const bPose *pose, const char *name)
bool id_can_have_animdata(const ID *id)
AnimData * BKE_animdata_from_id(const ID *id)
AnimationEvalContext BKE_animsys_eval_context_construct(struct Depsgraph *depsgraph, float eval_time) ATTR_WARN_UNUSED_RESULT
#define CTX_DATA_BEGIN(C, Type, instance, member)
Depsgraph * CTX_data_ensure_evaluated_depsgraph(const bContext *C)
ScrArea * CTX_wm_area(const bContext *C)
Depsgraph * CTX_data_depsgraph_pointer(const bContext *C)
Scene * CTX_data_scene(const bContext *C)
Object * CTX_data_edit_object(const bContext *C)
bool CTX_data_selected_objects(const bContext *C, blender::Vector< PointerRNA > *list)
Main * CTX_data_main(const bContext *C)
bool CTX_data_selected_pose_bones(const bContext *C, blender::Vector< PointerRNA > *list)
enum eContextObjectMode CTX_data_mode_enum(const bContext *C)
int BKE_fcurve_bezt_binarysearch_index(const BezTriple array[], float frame, int arraylen, bool *r_replace)
void BKE_fcurve_handles_recalc(FCurve *fcu)
FCurve * BKE_fcurve_find_by_rna_context_ui(bContext *C, const PointerRNA *ptr, PropertyRNA *prop, int rnaindex, AnimData **r_animdata, bAction **r_action, bool *r_driven, bool *r_special)
FCurve * BKE_fcurve_find(ListBase *list, const char rna_path[], int array_index)
bool BKE_fcurve_is_empty(const FCurve *fcu)
bool BKE_fcurve_is_protected(const FCurve *fcu)
float calculate_fcurve(PathResolvedRNA *anim_rna, FCurve *fcu, const AnimationEvalContext *anim_eval_context)
void BKE_fcurve_delete_key(FCurve *fcu, int index)
const char * BKE_idtype_idcode_to_name(short idcode)
bool BKE_id_is_editable(const Main *bmain, const ID *id)
float BKE_nla_tweakedit_remap(AnimData *adt, float cframe, short mode)
bool BKE_nlastrip_has_curves_for_property(const PointerRNA *ptr, const PropertyRNA *prop)
void BKE_reportf(ReportList *reports, eReportType type, const char *format,...) ATTR_PRINTF_FORMAT(3
void BKE_report(ReportList *reports, eReportType type, const char *message)
float BKE_scene_frame_get(const Scene *scene)
#define BLI_assert_msg(a, msg)
void BLI_kdtree_nd_ free(KDTree *tree)
#define LISTBASE_FOREACH(type, var, list)
MINLINE int compare_ff_relative(float a, float b, float max_diff, int max_ulps)
bool bool BLI_str_quoted_substr(const char *__restrict str, const char *__restrict prefix, char *result, size_t result_maxncpy)
size_t BLI_str_escape(char *__restrict dst, const char *__restrict src, size_t dst_maxncpy) ATTR_NONNULL(1
#define CTX_IFACE_(context, msgid)
#define BLT_I18NCONTEXT_OPERATOR_DEFAULT
void DEG_id_tag_update(ID *id, unsigned int flags)
ID and Library types, which are fundamental for SDNA.
@ ID_RECALC_ANIMATION_NO_FLUSH
Object is a sort of wrapper for general info.
@ USER_ANIM_KEY_CHANNEL_ROTATION_MODE
@ USER_ANIM_KEY_CHANNEL_SCALE
@ USER_ANIM_KEY_CHANNEL_ROTATION
@ USER_ANIM_KEY_CHANNEL_LOCATION
@ USER_ANIM_KEY_CHANNEL_CUSTOM_PROPERTIES
bool ED_operator_areaactive(bContext *C)
Read Guarded memory(de)allocation.
#define MEM_recallocN(vmemh, len)
@ PROP_STRING_SEARCH_SUGGESTION
void UI_context_update_anim_flag(const bContext *C)
void UI_popup_menu_end(bContext *C, uiPopupMenu *pup)
void uiItemS(uiLayout *layout)
uiPopupMenu * UI_popup_menu_begin(bContext *C, const char *title, int icon) ATTR_NONNULL()
uiBut * UI_context_active_but_prop_get(const bContext *C, PointerRNA *r_ptr, PropertyRNA **r_prop, int *r_index)
uiLayout * UI_popup_menu_layout(uiPopupMenu *pup)
void uiItemStringO(uiLayout *layout, const char *name, int icon, const char *opname, const char *propname, const char *value)
bool UI_but_flag_is_set(uiBut *but, int flag)
void ANIM_deselect_keys_in_animation_editors(bContext *C)
void append(const T &value)
bool is_action_layered() const
void merge(const CombinedKeyingResult &other)
int get_count(const SingleKeyingResult result) const
void generate_reports(ReportList *reports, eReportType report_level=RPT_ERROR)
const Depsgraph * depsgraph
static bool is_idproperty_keyable(IDProperty *id_prop, PointerRNA *ptr, PropertyRNA *prop)
void ANIM_OT_keyframe_insert_menu(wmOperatorType *ot)
static int delete_key_v3d_invoke(bContext *C, wmOperator *op, const wmEvent *)
bool fcurve_is_changed(PointerRNA ptr, PropertyRNA *prop, FCurve *fcu, const AnimationEvalContext *anim_eval_context)
Lesser Keyframe Checking API call.
static int clear_anim_v3d_invoke(bContext *C, wmOperator *op, const wmEvent *)
static int insert_key_exec(bContext *C, wmOperator *op)
static int delete_key_exec(bContext *C, wmOperator *op)
static int insert_key_button_exec(bContext *C, wmOperator *op)
void ANIM_OT_keyframe_insert(wmOperatorType *ot)
static int delete_key_button_exec(bContext *C, wmOperator *op)
void ANIM_OT_keyframe_clear_button(wmOperatorType *ot)
void ANIM_OT_keyframe_insert_by_name(wmOperatorType *ot)
static int clear_key_button_exec(bContext *C, wmOperator *op)
void ANIM_OT_keyframe_delete(wmOperatorType *ot)
void ED_keyframes_add(FCurve *fcu, int num_keys_to_add)
static int insert_key_invoke(bContext *C, wmOperator *op, const wmEvent *)
void ANIM_OT_keyframe_clear_v3d(wmOperatorType *ot)
static bool can_delete_key(FCurve *fcu, Object *ob, ReportList *reports)
bool fcurve_frame_has_keyframe(const FCurve *fcu, float frame)
Lesser Keyframe Checking API call.
void ANIM_OT_keyframe_insert_button(wmOperatorType *ot)
static bool object_frame_has_keyframe(Object *ob, float frame)
static KeyingSet * keyingset_get_from_op_with_error(wmOperator *op, PropertyRNA *prop, Scene *scene)
void update_autoflags_fcurve(FCurve *fcu, bContext *C, ReportList *reports, PointerRNA *ptr)
Lesser Key-framing API call.
static int insert_key_menu_invoke(bContext *C, wmOperator *op, const wmEvent *)
static int keyframe_insert_with_keyingset_exec(bContext *C, wmOperator *op)
static bool get_selection(bContext *C, blender::Vector< PointerRNA > *r_selection)
static bool modify_key_op_poll(bContext *C)
static int clear_anim_v3d_exec(bContext *C, wmOperator *)
static int insert_key_with_keyingset(bContext *C, wmOperator *op, KeyingSet *ks)
void ANIM_OT_keyframe_delete_v3d(wmOperatorType *ot)
static blender::Vector< RNAPath > construct_rna_paths(PointerRNA *ptr)
static bool assigned_action_has_keyframe_at(AnimData &adt, float frame)
static int delete_key_v3d_without_keying_set(bContext *C, wmOperator *op)
static bool can_delete_fcurve(FCurve *fcu, Object *ob)
void ANIM_OT_keyframe_delete_button(wmOperatorType *ot)
bool id_frame_has_keyframe(ID *id, float frame)
Main Keyframe Checking API call.
void ANIM_OT_keyframe_delete_by_name(wmOperatorType *ot)
static int delete_key_using_keying_set(bContext *C, wmOperator *op, KeyingSet *ks)
static int delete_key_v3d_exec(bContext *C, wmOperator *op)
static int insert_key(bContext *C, wmOperator *op)
void ANIM_keyingset_visit_for_search_no_poll(const bContext *C, PointerRNA *, PropertyRNA *, const char *, blender::FunctionRef< void(StringPropertySearchVisitParams)> visit_fn)
bool ANIM_keyingset_find_id(KeyingSet *keyingset, ID *id)
KeyingSet * ANIM_scene_get_active_keyingset(const Scene *scene)
KeyingSet * ANIM_keyingset_get_from_idname(Scene *scene, const char *idname)
KeyingSet * ANIM_keyingset_get_from_enum_type(Scene *scene, int type)
const EnumPropertyItem * ANIM_keying_sets_enum_itemf(bContext *C, PointerRNA *, PropertyRNA *, bool *r_free)
int ANIM_apply_keyingset(bContext *C, blender::Vector< PointerRNA > *sources, KeyingSet *keyingset, const blender::animrig::ModifyKeyMode mode, const float cfra)
void MEM_freeN(void *vmemh)
Vector< FCurve * > fcurves_for_assigned_action(AnimData *adt)
void update_autoflags_fcurve_direct(FCurve *fcu, PropertyRNA *prop)
Vector< float > get_rna_values(PointerRNA *ptr, PropertyRNA *prop)
int clear_keyframe(Main *bmain, ReportList *reports, ID *id, const RNAPath &rna_path)
int delete_keyframe(Main *bmain, ReportList *reports, ID *id, const RNAPath &rna_path, float cfra)
Main Delete Key-Framing API call.
bool fcurve_delete_keyframe_at_time(FCurve *fcurve, float time)
bool animdata_remove_empty_action(AnimData *adt)
void animdata_fcurve_delete(bAnimContext *ac, AnimData *adt, FCurve *fcu)
bool mode_set(bContext *C, eObjectMode mode)
GPU_SHADER_INTERFACE_INFO(overlay_edit_curve_handle_iface, "vert").flat(Type pos vertex_in(1, Type::UINT, "data") .vertex_out(overlay_edit_curve_handle_iface) .geometry_layout(PrimitiveIn Frequency::GEOMETRY storage_buf(1, Qualifier::READ, "uint", "data[]", Frequency::GEOMETRY) .push_constant(Type Frequency::GEOMETRY selection[]
PropertyRNA * RNA_struct_find_property(PointerRNA *ptr, const char *identifier)
PropertyType RNA_property_type(PropertyRNA *prop)
void RNA_property_enum_items_gettexted(bContext *C, PointerRNA *ptr, PropertyRNA *prop, const EnumPropertyItem **r_item, int *r_totitem, bool *r_free)
bool RNA_property_anim_editable(const PointerRNA *ptr, PropertyRNA *prop_orig)
int RNA_property_enum_get(PointerRNA *ptr, PropertyRNA *prop)
std::string RNA_property_string_get(PointerRNA *ptr, PropertyRNA *prop)
bool RNA_boolean_get(PointerRNA *ptr, const char *name)
void RNA_enum_set(PointerRNA *ptr, const char *name, int value)
int RNA_enum_get(PointerRNA *ptr, const char *name)
const char * RNA_property_identifier(const PropertyRNA *prop)
PointerRNA RNA_id_pointer_create(ID *id)
PropertyRNA * RNA_def_string(StructOrFunctionRNA *cont_, const char *identifier, const char *default_value, const int maxlen, const char *ui_name, const char *ui_description)
void RNA_def_property_string_search_func_runtime(PropertyRNA *prop, StringPropertySearchFunc search_fn, const eStringPropertySearchFlag search_flag)
PropertyRNA * RNA_def_enum(StructOrFunctionRNA *cont_, const char *identifier, const EnumPropertyItem *items, const int default_value, const char *ui_name, const char *ui_description)
PropertyRNA * RNA_def_boolean(StructOrFunctionRNA *cont_, const char *identifier, const bool default_value, const char *ui_name, const char *ui_description)
void RNA_def_property_flag(PropertyRNA *prop, PropertyFlag flag)
void RNA_def_enum_funcs(PropertyRNA *prop, EnumPropertyItemFunc itemfunc)
std::optional< std::string > RNA_path_from_ID_to_property(const PointerRNA *ptr, PropertyRNA *prop)
bool RNA_path_resolve_property(const PointerRNA *ptr, const char *path, PointerRNA *r_ptr, PropertyRNA **r_prop)
const EnumPropertyItem rna_enum_dummy_DEFAULT_items[]
std::optional< int > index
bool(* poll)(bContext *C) ATTR_WARN_UNUSED_RESULT
int(* invoke)(bContext *C, wmOperator *op, const wmEvent *event) ATTR_WARN_UNUSED_RESULT
int(* exec)(bContext *C, wmOperator *op) ATTR_WARN_UNUSED_RESULT
struct ReportList * reports
struct wmOperatorType * type
void WM_event_add_notifier(const bContext *C, uint type, void *reference)
void WM_operator_properties_confirm_or_exec(wmOperatorType *ot)
std::string WM_operatortype_name(wmOperatorType *ot, PointerRNA *properties)
int WM_operator_confirm_ex(bContext *C, wmOperator *op, const char *title, const char *message, const char *confirm_text, int icon, bool cancel_default)