67 if (typeinfo !=
nullptr) {
108 if (iat->
adt ==
nullptr) {
137 if (adt ==
nullptr) {
144 BKE_report(reports,
RPT_ERROR,
"Cannot change action, as it is still being edited in NLA");
156 return !is_tweaking_strip;
161 const int idcode =
GS(owner->
name);
163 if (action ==
nullptr) {
177 if (action->
idroot == 0) {
183 return (action->
idroot == idcode);
208 "Expecting action un-assignment to always work when not in NLA tweak mode");
216 BLI_assert_msg(unassign_ok,
"Expecting tmpaction un-assignment to always work");
245 if (adt ==
nullptr) {
282 std::optional<Library *> owner_library,
292 if (adt ==
nullptr) {
317 reinterpret_cast<ID *
>(dadt->
action),
324 reinterpret_cast<ID *
>(dadt->
tmpact),
329 else if (do_id_user) {
373 if ((id_to && id_from) && (
GS(id_to->
name) !=
GS(id_from->
name))) {
390 const bool set_newid,
391 const bool do_linked_id)
405 const bool assign_ok =
assign_action(&cloned_action->wrap(), *
id);
406 BLI_assert_msg(assign_ok,
"Expected action assignment to work when copying animdata");
418 const bool assign_ok =
assign_tmpaction(&cloned_action->wrap(), {*id, *adt});
419 BLI_assert_msg(assign_ok,
"Expected tmp-action assignment to work when copying animdata");
440 const uint duplicate_flags)
454 if (
ELEM(
nullptr, dst, src)) {
462 "Merging AnimData blocks while editing NLA is dangerous as it may cause data corruption");
495 ListBase drivers = {
nullptr,
nullptr};
507 if (dtar->id == src_id) {
532 return (path && basepath) &&
STRPREFIX(path, basepath);
536 const char *old_basepath,
537 const char *new_basepath)
540 if (
STREQ(old_basepath, new_basepath)) {
559 const char *src_basepath,
560 const char *dst_basepath)
563 if (
ELEM(
nullptr, srcAct, dstAct, src_basepath, dst_basepath)) {
566 "srcAct: %p, dstAct: %p, src_basepath: %p, dst_basepath: %p has insufficient "
570 (
void *)src_basepath,
571 (
void *)dst_basepath);
584 fcurves_to_move.
append(&fcurve);
589 for (
FCurve *fcurve_to_move : fcurves_to_move) {
597 const char *src_basepath,
598 const char *dst_basepath)
613 AnimData *srcAdt =
nullptr, *dstAdt =
nullptr;
616 if (
ELEM(
nullptr, srcID, dstID)) {
618 CLOG_ERROR(&
LOG,
"no source or destination ID to separate AnimData with");
627 if (
ELEM(
nullptr, srcAdt, dstAdt)) {
637 if (dstAdt->action == srcAdt->
action) {
639 "Source and Destination share animation! "
640 "('%s' and '%s' both use '%s') Making new empty action",
647 BLI_assert_msg(unassign_ok,
"Expected Action unassignment to work");
653 if (!dstAdt->action) {
669 basepath_change->src_basepath,
670 basepath_change->dst_basepath);
678 srcAdt, dstAdt, basepath_change->src_basepath, basepath_change->dst_basepath);
711 char *prefixPtr = strstr(oldpath, prefix);
712 if (prefixPtr ==
nullptr) {
716 char *oldNamePtr = strstr(oldpath, oldName);
717 if (oldNamePtr ==
nullptr) {
721 int prefixLen = strlen(prefix);
722 int oldNameLen = strlen(oldName);
727 if (prefixPtr + prefixLen == oldNamePtr) {
731 const char *postfixPtr = oldNamePtr + oldNameLen;
732 char *newPath =
nullptr;
735 if (prefixPtr > oldpath) {
779 bool is_changed =
false;
781 for (
FCurve *fcu : curves) {
782 if (fcu->rna_path ==
nullptr) {
785 const char *old_path = fcu->rna_path;
788 owner_id, prefix, oldKey, newKey, fcu->rna_path, verify_paths);
792 if (fcu->rna_path != old_path) {
795 if (oldName !=
nullptr && (agrp !=
nullptr) &&
STREQ(oldName, agrp->
name)) {
814 bool is_changed =
false;
818 if (fcu->rna_path !=
nullptr) {
819 const char *old_rna_path = fcu->rna_path;
821 owner_id, prefix, oldKey, newKey, fcu->rna_path, verify_paths);
822 is_changed |= (fcu->rna_path != old_rna_path);
824 if (fcu->driver ==
nullptr) {
833 if (dtar->rna_path && dtar->id) {
834 const char *old_rna_path = dtar->rna_path;
836 dtar->id, prefix, oldKey, newKey, dtar->rna_path, verify_paths);
837 is_changed |= (dtar->rna_path != old_rna_path);
840 if (strstr(prefix,
"bones")) {
841 if (((dtar->id) && (
GS(dtar->id->name) ==
ID_OB) &&
842 (!ref_id || ((
Object *)(dtar->id))->data == ref_id)) &&
843 (dtar->pchan_name[0]) &&
STREQ(oldName, dtar->pchan_name))
846 STRNCPY(dtar->pchan_name, newName);
866 bool is_changed =
false;
870 if (strip->act !=
nullptr) {
872 strip->act, strip->action_slot_handle);
874 owner_id, prefix, oldName, newName, oldKey, newKey, fcurves, verify_paths);
875 if (is_changed_action) {
878 is_changed |= is_changed_action;
883 owner_id, prefix, oldName, newName, oldKey, newKey, &strip->strips, verify_paths);
903 if (
ELEM(
nullptr, owner_id, old_path)) {
911 if ((oldName !=
nullptr) && (newName !=
nullptr)) {
913 const size_t name_old_len = strlen(oldName);
914 const size_t name_new_len = strlen(newName);
915 char *name_old_esc =
static_cast<char *
>(
917 char *name_new_esc =
static_cast<char *
>(
932 printf(
"%s | %s | oldpath = %p ", oldN, newN, old_path);
960 if (
ELEM(
nullptr, owner_id, act)) {
965 if ((oldName !=
nullptr) && (newName !=
nullptr)) {
967 const size_t name_old_len = strlen(oldName);
968 const size_t name_new_len = strlen(newName);
969 char *name_old_esc =
static_cast<char *
>(
971 char *name_new_esc =
static_cast<char *
>(
1005 const char *oldName,
1006 const char *newName,
1013 if (
ELEM(
nullptr, owner_id, adt)) {
1016 bool is_self_changed =
false;
1018 if ((oldName !=
nullptr) && (newName !=
nullptr)) {
1020 const size_t name_old_len = strlen(oldName);
1021 const size_t name_new_len = strlen(newName);
1022 char *name_old_esc =
static_cast<char *
>(
1024 char *name_new_esc =
static_cast<char *
>(
1041 owner_id, prefix, oldName, newName, oldN, newN, fcurves, verify_paths))
1050 owner_id, prefix, oldName, newName, oldN, newN, fcurves, verify_paths))
1057 owner_id, ref_id, prefix, oldName, newName, oldN, newN, &adt->
drivers, verify_paths);
1061 owner_id, prefix, oldName, newName, oldN, newN, &nlt->strips, verify_paths);
1064 if (is_self_changed) {
1078 bool any_removed =
false;
1084 for (fcu =
static_cast<FCurve *
>(curves->
first); fcu; fcu = fcn) {
1101 bool any_removed =
false;
1108 *strip->act, strip->action_slot_handle, prefix);
1125 bool any_removed =
false;
1162 if (!base_path.has_value()) {
1182 for (
FCurve *fcu : fcurves) {
1183 if (!func(
id, fcu)) {
1192 if (!func(
id, fcu)) {
1208 strip->act, strip->action_slot_handle);
1274 if (adt !=
nullptr) {
1276 const auto wrapper = [&func](
ID *id,
FCurve *fcurve) {
1287 const auto wrapper = [&func](
ID *id,
FCurve *fcurve) {
1329 if (!iat || !iat->
adt) {
1334 if (adt ==
nullptr) {
1393 nullptr,
const_cast<AnimData *
>(adt), [&](
const ID *,
const FCurve *fcurve) {
1398 return !looped_until_end;
Functionality to iterate an Action in various ways.
Functions for backward compatibility with the legacy Action API.
Blender kernel action and pose functionality.
eAnimData_MergeCopy_Modes
void BKE_animdata_main_cb(struct Main *bmain, blender::FunctionRef< void(ID *, AnimData *)> func)
void BKE_fcurve_foreach_id(FCurve *fcu, LibraryForeachIDData *data)
void BKE_fcurve_blend_write_listbase(BlendWriter *writer, ListBase *fcurves)
void BKE_fcurve_blend_read_data_listbase(BlendDataReader *reader, ListBase *fcurves)
void BKE_fcurves_free(ListBase *list)
void BKE_fcurves_copy(ListBase *dst, ListBase *src)
void BKE_fcurve_free(FCurve *fcu)
#define DRIVER_TARGETS_USED_LOOPER_BEGIN(dvar)
#define DRIVER_TARGETS_LOOPER_END
@ IDTYPE_FLAGS_NO_ANIMDATA
const IDTypeInfo * BKE_idtype_get_info_from_idcode(short id_code)
struct ID * BKE_id_copy_in_lib(Main *bmain, std::optional< Library * > owner_library, const ID *id, std::optional< const ID * > new_owner_id, ID **new_id_p, int flag)
ID * BKE_id_copy(Main *bmain, const ID *id)
@ LIB_ID_CREATE_NO_USER_REFCOUNT
#define BKE_LIB_FOREACHID_PROCESS_FUNCTION_CALL(data_, func_call_)
#define BKE_LIB_FOREACHID_PROCESS_IDSUPER(data_, id_super_, cb_flag_)
void BKE_nla_tracks_copy_from_adt(Main *bmain, AnimData *adt_dest, const AnimData *adt_source, int flag)
void BKE_nla_tweakmode_exit(OwnedAnimData owned_adt)
void BKE_nla_tweakmode_exit_nofollowptr(AnimData *adt)
void BKE_nla_tracks_copy(Main *bmain, ListBase *dst, const ListBase *src, int flag)
void BKE_nla_blend_write(BlendWriter *writer, ListBase *tracks)
void BKE_nla_tracks_free(ListBase *tracks, bool do_id_user)
void BKE_nla_liboverride_post_process(ID *id, AnimData *adt)
bool BKE_nlatrack_is_enabled(const AnimData &adt, const NlaTrack &nlt)
void BKE_nla_blend_read_data(BlendDataReader *reader, ID *id_owner, ListBase *tracks)
void BKE_nla_strip_foreach_id(NlaStrip *strip, LibraryForeachIDData *data)
void BKE_report(ReportList *reports, eReportType type, const char *message)
#define BLI_array_alloca(arr, realsize)
#define BLI_assert_unreachable()
#define BLI_assert_msg(a, msg)
A dynamically sized string ADT.
char * BLI_dynstr_get_cstring(const DynStr *ds) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT ATTR_NONNULL()
void BLI_dynstr_nappend(DynStr *__restrict ds, const char *cstr, int len) ATTR_NONNULL()
DynStr * BLI_dynstr_new(void) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT
void BLI_dynstr_free(DynStr *ds) ATTR_NONNULL()
void BLI_dynstr_append(DynStr *__restrict ds, const char *cstr) ATTR_NONNULL()
void void void BLI_movelisttolist(ListBase *dst, ListBase *src) ATTR_NONNULL(1
#define LISTBASE_FOREACH(type, var, list)
BLI_INLINE void BLI_listbase_clear(ListBase *lb)
BLI_INLINE bool BLI_listbase_is_empty(const ListBase *lb)
#define LISTBASE_FOREACH_MUTABLE(type, var, list)
void BLI_addtail(ListBase *listbase, void *vlink) ATTR_NONNULL(1)
void BLI_remlink(ListBase *listbase, void *vlink) ATTR_NONNULL(1)
char * BLI_sprintfN(const char *__restrict format,...) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1) ATTR_MALLOC ATTR_PRINTF_FORMAT(1
char * STRNCPY(char(&dst)[N], const char *src)
size_t BLI_str_escape(char *__restrict dst, const char *__restrict src, size_t dst_maxncpy) ATTR_NONNULL(1
#define STRNCPY_UTF8(dst, src)
#define UNUSED_VARS_NDEBUG(...)
#define BLO_write_struct(writer, struct_name, data_ptr)
void BLO_write_string(BlendWriter *writer, const char *data_ptr)
#define BLO_read_struct_list(reader, struct_name, list)
#define BLO_read_struct(reader, struct_name, ptr_p)
#define CLOG_ERROR(clg_ref,...)
#define CLOG_WARN(clg_ref,...)
void DEG_id_tag_update(ID *id, unsigned int flags)
ID and Library types, which are fundamental for SDNA.
#define ID_IS_LINKED(_id)
#define ID_IS_OVERRIDE_LIBRARY(_id)
#define ID_NEW_SET(_id, _idn)
Read Guarded memory(de)allocation.
static bool fcurves_path_remove_from_listbase(const char *prefix, ListBase *curves)
bool BKE_animdata_copy_id(Main *bmain, ID *id_to, ID *id_from, const int flag)
bool BKE_animdata_id_is_animated(const ID *id)
static bool adt_apply_all_fcurves_cb(ID *id, AnimData *adt, const IDFCurveCallback func)
static void animdata_copy_id_action(Main *bmain, ID *id, const bool set_newid, const bool do_linked_id)
static bool nlastrips_apply_all_curves_cb(ID *id, ListBase *strips, const IDFCurveCallback func)
bool BKE_animdata_action_ensure_idroot(const ID *owner, bAction *action)
void BKE_action_fix_paths_rename(ID *owner_id, bAction *act, animrig::slot_handle_t slot_handle, const char *prefix, const char *oldName, const char *newName, int oldSubscript, int newSubscript, bool verify_paths)
bool BKE_animdata_fix_paths_remove(ID *id, const char *prefix)
void BKE_animdata_merge_copy(Main *bmain, ID *dst_id, ID *src_id, eAnimData_MergeCopy_Modes action_mode, bool fix_drivers)
void BKE_animdata_blend_write(BlendWriter *writer, ID *id)
static bool drivers_path_rename_fix(ID *owner_id, ID *ref_id, const char *prefix, const char *oldName, const char *newName, const char *oldKey, const char *newKey, ListBase *curves, bool verify_paths)
static bool check_rna_path_is_valid(ID *owner_id, const char *path)
AnimData * BKE_animdata_ensure_id(ID *id)
static bool nlastrips_path_rename_fix(ID *owner_id, const char *prefix, const char *oldName, const char *newName, const char *oldKey, const char *newKey, ListBase *strips, bool verify_paths)
bool id_can_have_animdata(const ID *id)
static bool fcurves_apply_cb(ID *id, blender::Span< FCurve * > fcurves, const IDFCurveCallback func)
void BKE_animdata_foreach_id(AnimData *adt, LibraryForeachIDData *data)
bool id_type_can_have_animdata(const short id_type)
void BKE_fcurves_id_cb(ID *id, const FunctionRef< void(ID *, FCurve *)> func)
bool BKE_animdata_action_editable(const AnimData *adt)
bool BKE_animdata_drivers_remove_for_rna_struct(ID &owner_id, StructRNA &type, void *data)
FunctionRef< bool(ID *, FCurve *)> IDFCurveCallback
bool BKE_animdata_set_action(ReportList *reports, ID *id, bAction *act)
void BKE_animdata_free(ID *id, const bool do_id_user)
static bool fcurves_listbase_apply_cb(ID *id, ListBase *fcurves, const IDFCurveCallback func)
static bool animpath_matches_basepath(const char path[], const char basepath[])
AnimData * BKE_animdata_from_id(const ID *id)
void BKE_fcurves_main_cb(Main *bmain, const FunctionRef< void(ID *, FCurve *)> func)
static bool nlastrips_path_remove_fix(const char *prefix, ListBase *strips)
void BKE_animdata_blend_read_data(BlendDataReader *reader, ID *id)
static char * rna_path_rename_fix(ID *owner_id, const char *prefix, const char *oldName, const char *newName, char *oldpath, bool verify_paths)
AnimData * BKE_animdata_copy_in_lib(Main *bmain, std::optional< Library * > owner_library, AnimData *adt, const int flag)
void BKE_animdata_liboverride_post_process(ID *id)
void BKE_animdata_duplicate_id_action(Main *bmain, ID *id, const uint duplicate_flags)
static void animpath_update_basepath(FCurve *fcu, const char *old_basepath, const char *new_basepath)
void BKE_animdata_transfer_by_basepath(Main *bmain, ID *srcID, ID *dstID, ListBase *basepaths)
void BKE_animdata_copy_id_action(Main *bmain, ID *id)
static void action_move_fcurves_by_basepath(bAction *srcAct, const animrig::slot_handle_t src_slot_handle, bAction *dstAct, const animrig::slot_handle_t dst_slot_handle, const char *src_basepath, const char *dst_basepath)
char * BKE_animsys_fix_rna_path_rename(ID *owner_id, char *old_path, const char *prefix, const char *oldName, const char *newName, int oldSubscript, int newSubscript, bool verify_paths)
AnimData * BKE_animdata_copy(Main *bmain, AnimData *adt, const int flag)
bool BKE_animdata_driver_path_remove(ID *id, const char *prefix)
static void animdata_move_drivers_by_basepath(AnimData *srcAdt, AnimData *dstAdt, const char *src_basepath, const char *dst_basepath)
void BKE_animdata_fix_paths_rename(ID *owner_id, AnimData *adt, ID *ref_id, const char *prefix, const char *oldName, const char *newName, int oldSubscript, int newSubscript, bool verify_paths)
static bool fcurves_path_rename_fix(ID *owner_id, const char *prefix, const char *oldName, const char *newName, const char *oldKey, const char *newKey, blender::Span< FCurve * > curves, bool verify_paths)
BMesh const char void * data
void append(const T &value)
Slot & slot_add_for_id(const ID &animated_id)
bool is_action_legacy() const
bool is_action_layered() const
bool is_slot_animated(slot_handle_t slot_handle) const
static void users_invalidate(Main &bmain)
static constexpr slot_handle_t unassigned
void * MEM_callocN(size_t len, const char *str)
void * MEM_dupallocN(const void *vmemh)
void MEM_freeN(void *vmemh)
Vector< FCurve * > fcurves_for_action_slot(bAction *action, slot_handle_t slot_handle)
bool action_fcurves_remove(bAction &action, slot_handle_t slot_handle, StringRefNull rna_path_prefix)
bool action_treat_as_legacy(const bAction &action)
void foreach_fcurve_in_action_slot(Action &action, slot_handle_t handle, FunctionRef< void(FCurve &fcurve)> callback)
void action_fcurve_move(Action &action_dst, slot_handle_t action_slot_dst, Action &action_src, FCurve &fcurve)
Action & action_add(Main &bmain, StringRefNull name)
decltype(::ActionSlot::handle) slot_handle_t
bool assign_tmpaction(bAction *action, OwnedAnimData owned_adt)
bool unassign_action(ID &animated_id)
bool assign_action(bAction *action, ID &animated_id)
void action_slots_user_cache_invalidate(Main &bmain)
bool prop_is_animated(const AnimData *adt, StringRefNull rna_path, int array_index)
bNodeTree * node_tree_from_id(ID *id)
PointerRNA RNA_pointer_create_discrete(ID *id, StructRNA *type, void *data)
PointerRNA RNA_id_pointer_create(ID *id)
std::optional< std::string > RNA_path_from_ID_to_struct(const PointerRNA *ptr)
bool RNA_path_resolve_property(const PointerRNA *ptr, const char *path, PointerRNA *r_ptr, PropertyRNA **r_prop)
char tmp_last_slot_identifier[258]
char last_slot_identifier[258]