diff --git a/source/blender/animrig/ANIM_keyframing.hh b/source/blender/animrig/ANIM_keyframing.hh index 7a92252c3c8..d7f32d508f1 100644 --- a/source/blender/animrig/ANIM_keyframing.hh +++ b/source/blender/animrig/ANIM_keyframing.hh @@ -194,4 +194,16 @@ int insert_key_action(Main *bmain, eInsertKeyFlags insert_key_flag, eBezTriple_KeyframeType key_type); +/** Insert keys to the ID of the given PointerRNA for the given RNA paths. Tries to create an + * action if none exists yet. + * \param scene_frame is expected to be not NLA mapped as that happens within the function. + */ +void insert_key_rna(PointerRNA *rna_pointer, + const blender::Span rna_paths, + float scene_frame, + eInsertKeyFlags insert_key_flags, + eBezTriple_KeyframeType key_type, + Main *bmain, + ReportList *reports); + } // namespace blender::animrig diff --git a/source/blender/animrig/intern/keyframing.cc b/source/blender/animrig/intern/keyframing.cc index c66c3128ec3..693007a0f82 100644 --- a/source/blender/animrig/intern/keyframing.cc +++ b/source/blender/animrig/intern/keyframing.cc @@ -1003,4 +1003,79 @@ int insert_key_action(Main *bmain, return inserted_keys; } +static blender::Vector get_keyframe_values(PointerRNA *ptr, + PropertyRNA *prop, + const bool visual_key) +{ + Vector values; + + if (visual_key && visualkey_can_use(ptr, prop)) { + /* Visual-keying is only available for object and pchan datablocks, as + * it works by keyframing using a value extracted from the final matrix + * instead of using the kt system to extract a value. + */ + values = visualkey_get_values(ptr, prop); + } + else { + values = get_rna_values(ptr, prop); + } + return values; +} + +void insert_key_rna(PointerRNA *rna_pointer, + const blender::Span rna_paths, + const float scene_frame, + const eInsertKeyFlags insert_key_flags, + const eBezTriple_KeyframeType key_type, + Main *bmain, + ReportList *reports) +{ + ID *id = rna_pointer->owner_id; + bAction *action = ED_id_action_ensure(bmain, id); + if (action == nullptr) { + BKE_reportf(reports, + RPT_ERROR, + "Could not insert keyframe, as this type does not support animation data (ID = " + "%s)", + id->name); + return; + } + + AnimData *adt = BKE_animdata_from_id(id); + const float nla_frame = BKE_nla_tweakedit_remap(adt, scene_frame, NLATIME_CONVERT_UNMAP); + const bool visual_keyframing = insert_key_flags & INSERTKEY_MATRIX; + + int insert_key_count = 0; + for (const std::string &rna_path : rna_paths) { + PointerRNA ptr; + PropertyRNA *prop = nullptr; + const bool path_resolved = RNA_path_resolve_property( + rna_pointer, rna_path.c_str(), &ptr, &prop); + if (!path_resolved) { + BKE_reportf(reports, + RPT_ERROR, + "Could not insert keyframe, as this property does not exist (ID = " + "%s, path = %s)", + id->name, + rna_path.c_str()); + continue; + } + std::string rna_path_id_to_prop = RNA_path_from_ID_to_property(&ptr, prop); + Vector rna_values = get_keyframe_values(&ptr, prop, visual_keyframing); + + insert_key_count += insert_key_action(bmain, + action, + rna_pointer, + rna_path_id_to_prop, + nla_frame, + rna_values.as_span(), + insert_key_flags, + key_type); + } + + if (insert_key_count == 0) { + BKE_reportf(reports, RPT_ERROR, "Failed to insert any keys"); + } +} + } // namespace blender::animrig diff --git a/source/blender/editors/animation/keyframing.cc b/source/blender/editors/animation/keyframing.cc index 7189abf2562..808948c05f9 100644 --- a/source/blender/editors/animation/keyframing.cc +++ b/source/blender/editors/animation/keyframing.cc @@ -395,84 +395,6 @@ static blender::Vector construct_rna_paths(PointerRNA *ptr) return paths; } -static blender::Vector get_keyframe_values(PointerRNA *ptr, - PropertyRNA *prop, - const bool visual_key) -{ - using namespace blender; - Vector values; - - if (visual_key && animrig::visualkey_can_use(ptr, prop)) { - /* Visual-keying is only available for object and pchan datablocks, as - * it works by keyframing using a value extracted from the final matrix - * instead of using the kt system to extract a value. - */ - values = animrig::visualkey_get_values(ptr, prop); - } - else { - values = animrig::get_rna_values(ptr, prop); - } - return values; -} - -static void insert_key_rna(PointerRNA *rna_pointer, - const blender::Span rna_paths, - const float scene_frame, - const eInsertKeyFlags insert_key_flags, - const eBezTriple_KeyframeType key_type, - Main *bmain, - ReportList *reports) -{ - using namespace blender; - - ID *id = rna_pointer->owner_id; - bAction *action = ED_id_action_ensure(bmain, id); - if (action == nullptr) { - BKE_reportf(reports, - RPT_ERROR, - "Could not insert keyframe, as this type does not support animation data (ID = " - "%s)", - id->name); - return; - } - - AnimData *adt = BKE_animdata_from_id(id); - const float nla_frame = BKE_nla_tweakedit_remap(adt, scene_frame, NLATIME_CONVERT_UNMAP); - const bool visual_keyframing = insert_key_flags & INSERTKEY_MATRIX; - - int insert_key_count = 0; - for (const std::string &rna_path : rna_paths) { - PointerRNA ptr; - PropertyRNA *prop = nullptr; - const bool path_resolved = RNA_path_resolve_property( - rna_pointer, rna_path.c_str(), &ptr, &prop); - if (!path_resolved) { - BKE_reportf(reports, - RPT_ERROR, - "Could not insert keyframe, as this property does not exist (ID = " - "%s, path = %s)", - id->name, - rna_path.c_str()); - continue; - } - std::string rna_path_id_to_prop = RNA_path_from_ID_to_property(&ptr, prop); - Vector rna_values = get_keyframe_values(&ptr, prop, visual_keyframing); - - insert_key_count += animrig::insert_key_action(bmain, - action, - rna_pointer, - rna_path_id_to_prop, - nla_frame, - rna_values.as_span(), - insert_key_flags, - key_type); - } - - if (insert_key_count == 0) { - BKE_reportf(reports, RPT_ERROR, "Failed to insert any keys"); - } -} - /* Fill the list with CollectionPointerLink depending on the mode of the context. */ static bool get_selection(bContext *C, ListBase *r_selection) { @@ -523,7 +445,7 @@ static int insert_key(bContext *C, wmOperator *op) PointerRNA id_ptr = collection_ptr_link->ptr; Vector rna_paths = construct_rna_paths(&collection_ptr_link->ptr); - insert_key_rna( + animrig::insert_key_rna( &id_ptr, rna_paths.as_span(), scene_frame, insert_key_flags, key_type, bmain, op->reports); }