Blender V5.0
ANIM_action.hh
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2023 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
10#pragma once
11
12#include "ANIM_fcurve.hh"
13#include "ANIM_keyframing.hh"
14
15#include "DNA_action_types.h"
16#include "DNA_anim_types.h"
17
18#include "BKE_action.hh"
19#include "BKE_anim_data.hh"
20
21#include "BLI_span.hh"
22#include "BLI_string_ref.hh"
23#include "BLI_vector.hh"
24
25#include "RNA_types.hh"
26
27#include <utility>
28
29struct FCurve;
30struct FCurve;
31struct ID;
32struct Main;
33struct PointerRNA;
34struct Main;
35
37
38/* Forward declarations for the types defined later in this file. */
39class Layer;
40class Strip;
41class Slot;
42
94class Action : public ::bAction {
95 public:
96 Action() = default;
101 Action(const Action &other) = delete;
102
103 /* Discriminators for 'legacy' and 'layered' Actions.
104 *
105 * Note: `is_action_legacy()` and `is_action_layered()` are transitional APIs,
106 * and should eventually be removed. See their documentation below for
107 * details.
108 */
115 bool is_empty() const;
133 bool is_action_legacy() const;
149 bool is_action_layered() const;
150
151 /* Action Layers access. */
154 const Layer *layer(int64_t index) const;
155 Layer *layer(int64_t index);
156
174 Layer &layer_add(std::optional<StringRefNull> name);
175
184 bool layer_remove(Layer &layer_to_remove);
185
193
194 /* Action Slot access. */
197 const Slot *slot(int64_t index) const;
198 Slot *slot(int64_t index);
199
209 const Slot *slot_for_handle(slot_handle_t handle) const;
210
221 void slot_display_name_set(Main &bmain, Slot &slot, StringRefNull new_display_name);
222
236 void slot_display_name_define(Slot &slot, StringRefNull new_display_name);
237
250 void slot_idtype_define(Slot &slot, ID_Type idtype);
251
265 void slot_identifier_set(Main &bmain, Slot &slot, StringRefNull new_identifier);
266
276 void slot_identifier_define(Slot &slot, StringRefNull new_identifier);
277
286 void slot_identifier_propagate(Main &bmain, const Slot &slot);
287
295
314 Slot &slot_add();
315
322
335 Slot &slot_add_for_id(const ID &animated_id);
336
348 bool slot_remove(Slot &slot_to_remove);
349
357 void slot_move_to_index(Slot &slot, int to_slot_index);
358
365 void slot_active_set(slot_handle_t slot_handle);
366
379
385
391 bool is_slot_animated(slot_handle_t slot_handle) const;
392
401 bool has_keyframes(slot_handle_t action_slot_handle) const ATTR_WARN_UNUSED_RESULT;
402
413
418
427
438
449
457 float2 get_frame_range_of_keys(bool include_modifiers) const ATTR_WARN_UNUSED_RESULT;
458
470 void slot_setup_for_id(Slot &slot, const ID &animated_id);
471
472 protected:
473 /* Friends for the purpose of adding/removing strip data on the action's strip
474 * data arrays. This is needed for the strip creation and removal code in
475 * `Strip` and `Layer`'s methods. */
476 friend Strip;
477 friend Layer;
478
480 int64_t find_layer_index(const Layer &layer) const;
481
483 int64_t find_slot_index(const Slot &slot) const;
484
494
510
511 private:
526 Slot &slot_allocate();
527
536 void slot_identifier_ensure_prefix(Slot &slot);
537};
538static_assert(sizeof(Action) == sizeof(::bAction),
539 "DNA struct and its C++ wrapper must have the same size");
540
551class Strip : public ::ActionStrip {
552 public:
561 enum class Type : int8_t { Keyframe = 0 };
562
563 /* Strips typically shouldn't be directly constructed or copied, because their
564 * data is actually stored in arrays on the action, and that data also needs
565 * to be created and managed along with the strips. */
566 Strip() = delete;
567
573 explicit Strip(const Strip &other) = default;
574
593 static Strip &create(Action &owning_action, const Strip::Type type);
594
601 Type type() const
602 {
603 return Type(this->strip_type);
604 }
605
609 bool is_infinite() const;
610
616 bool contains_frame(float frame_time) const;
617
622 bool is_last_frame(float frame_time) const;
623
634 void resize(float frame_start, float frame_end);
635
648 template<typename T> const T &data(const Action &owning_action) const;
649 template<typename T> T &data(Action &owning_action);
650};
651static_assert(sizeof(Strip) == sizeof(::ActionStrip),
652 "DNA struct and its C++ wrapper must have the same size");
653
669class Layer : public ::ActionLayer {
670 public:
671 Layer() = default;
672 Layer(const Layer &other) = delete;
673 ~Layer();
674
689
690 enum class Flags : uint8_t {
691 /* Set by default, cleared to mute. */
692 Enabled = (1 << 0),
693 /* When adding/removing a flag, also update the ENUM_OPERATORS() invocation below. */
694 };
695
696 Flags flags() const
697 {
698 return static_cast<Flags>(this->layer_flags);
699 }
700
701 enum class MixMode : int8_t {
703 Replace = 0,
707 Add = 2,
709 Subtract = 3,
711 Multiply = 4,
712 };
713
715 {
716 return static_cast<MixMode>(this->layer_mix_mode);
717 }
718
719 /* Strip array access. */
720 blender::Span<const Strip *> strips() const;
721 blender::Span<Strip *> strips();
722 const Strip *strip(int64_t index) const;
723 Strip *strip(int64_t index);
724
732 Strip &strip_add(Action &owning_action, Strip::Type strip_type);
733
742 bool strip_remove(Action &owning_action, Strip &strip);
743
744 protected:
749 int64_t find_strip_index(const Strip &strip) const;
750};
751static_assert(sizeof(Layer) == sizeof(::ActionLayer),
752 "DNA struct and its C++ wrapper must have the same size");
753
755
765class Slot : public ::ActionSlot {
766 public:
767 Slot();
768 explicit Slot(const Slot &other);
769 ~Slot();
770
777 void blend_read_post();
778
782 constexpr static slot_handle_t unassigned = 0;
783
788 constexpr static int identifier_length_min = 3;
789
790 constexpr static int identifier_length_max = MAX_ID_NAME;
793
811 std::string idtype_string() const;
812
826
836
859 bool is_suitable_for(const ID &animated_id) const;
860
867 bool has_idtype() const;
868
869 /* Flags access. */
870 enum class Flags : uint8_t {
872 Expanded = (1 << 0),
874 Selected = (1 << 1),
876 Active = (1 << 2),
877 /* When adding/removing a flag, also update the ENUM_OPERATORS() invocation,
878 * all the way below the Slot class. */
879 };
880 Flags flags() const;
881 bool is_expanded() const;
882 void set_expanded(bool expanded);
883 bool is_selected() const;
884 void set_selected(bool selected);
885 bool is_active() const;
886
888 Span<ID *> users(Main &bmain) const;
889
900 Vector<ID *> runtime_users();
901
908 void users_add(ID &animated_id);
909
916 void users_remove(ID &animated_id);
917
929 static void users_invalidate(Main &bmain);
930
952 void identifier_ensure_prefix();
953
954 protected:
955 friend Action;
956
960 void set_active(bool active);
961};
962static_assert(sizeof(Slot) == sizeof(::ActionSlot),
963 "DNA struct and its C++ wrapper must have the same size");
965
976 public:
977 /* Value of `Strip::type()` that corresponds to this type. */
978 static constexpr Strip::Type TYPE = Strip::Type::Keyframe;
979
980 StripKeyframeData() = default;
981 explicit StripKeyframeData(const StripKeyframeData &other);
983
984 /* Channelbag array access. */
987 const Channelbag *channelbag(int64_t index) const;
989
995 const Channelbag *channelbag_for_slot(const Slot &slot) const;
996 Channelbag *channelbag_for_slot(const Slot &slot);
997 const Channelbag *channelbag_for_slot(slot_handle_t slot_handle) const;
999
1007
1013
1021 bool channelbag_remove(Channelbag &channelbag_to_remove);
1022
1026 void slot_data_remove(slot_handle_t slot_handle);
1027
1033 void slot_data_duplicate(slot_handle_t source_slot_handle, slot_handle_t target_slot_handle);
1034
1040
1042 const Slot &slot,
1043 const FCurveDescriptor &fcurve_descriptor,
1044 float2 time_value,
1045 const KeyframeSettings &settings,
1046 eInsertKeyFlags insert_key_flags = INSERTKEY_NOFLAGS,
1047 std::optional<float2> cycle_range = std::nullopt);
1048};
1049static_assert(sizeof(StripKeyframeData) == sizeof(::ActionStripKeyframeData),
1050 "DNA struct and its C++ wrapper must have the same size");
1051
1062 public:
1063 Channelbag() = default;
1064 explicit Channelbag(const Channelbag &other);
1065 ~Channelbag();
1066
1067 /* FCurves access. */
1070 const FCurve *fcurve(int64_t index) const;
1071 FCurve *fcurve(int64_t index);
1072
1078 const FCurve *fcurve_find(const FCurveDescriptor &fcurve_descriptor) const;
1079 FCurve *fcurve_find(const FCurveDescriptor &fcurve_descriptor);
1080
1091 FCurve &fcurve_ensure(Main *bmain, const FCurveDescriptor &fcurve_descriptor);
1092
1104 FCurve *fcurve_create_unique(Main *bmain, const FCurveDescriptor &fcurve_descriptor);
1105
1133
1147
1161 bool fcurve_remove(FCurve &fcurve_to_remove);
1162
1171 void fcurve_remove_by_index(int64_t fcurve_index);
1172
1186 bool fcurve_detach(FCurve &fcurve_to_detach);
1187
1196 void fcurve_detach_by_index(int64_t fcurve_index);
1197
1207 void fcurve_move_to_index(FCurve &fcurve, int to_fcurve_index);
1208
1215 void fcurves_clear();
1216
1217 /* Channel group access. */
1220 const bActionGroup *channel_group(int64_t index) const;
1222
1233
1240 int channel_group_find_index(const bActionGroup *group) const;
1241
1249 int channel_group_containing_index(int fcurve_array_index);
1250
1263
1273
1284
1295 void channel_group_move_to_index(bActionGroup &group, int to_group_index);
1296
1306
1320
1321 protected:
1334 FCurve &fcurve_create(Main *bmain, const FCurveDescriptor &fcurve_descriptor);
1335
1336 private:
1353 void channel_group_remove_raw(int group_index);
1354
1396 void restore_channel_group_invariants();
1397};
1398
1399static_assert(sizeof(Channelbag) == sizeof(::ActionChannelbag),
1400 "DNA struct and its C++ wrapper must have the same size");
1401
1410 public:
1420 bool is_legacy() const;
1421
1427};
1428
1429static_assert(sizeof(ChannelGroup) == sizeof(::bActionGroup),
1430 "DNA struct and its C++ wrapper must have the same size");
1431
1441
1442/* ---------- Action & Slot Assignment --------------- */
1443
1444enum class ActionSlotAssignmentResult : int8_t {
1445 OK = 0,
1446 SlotNotFromAction = 1, /* Slot does not belong to the assigned Action. */
1447 SlotNotSuitable = 2, /* Slot is not suitable for the given ID type. */
1448 MissingAction = 3, /* No Action assigned yet, so cannot assign slot. */
1449};
1450
1457[[nodiscard]] bool is_action_assignable_to(const bAction *dna_action, ID_Type id_code);
1458
1476[[nodiscard]] bool assign_action(bAction *action, ID &animated_id);
1477
1487[[nodiscard]] bool assign_action(bAction *action, OwnedAnimData owned_adt);
1488
1489ActionSlotAssignmentResult assign_action_slot(Slot *slot_to_assign, ID &animated_id);
1490
1500 Slot *slot_to_assign,
1501 ID &animated_id);
1502
1521[[nodiscard]] Slot *assign_action_ensure_slot_for_keying(Action &action, ID &animated_id);
1522
1526[[nodiscard]] bool assign_tmpaction(bAction *action, OwnedAnimData owned_adt);
1527
1529 bAction *action, slot_handle_t slot_handle, OwnedAnimData owned_adt);
1530
1538[[nodiscard]] bool unassign_action(ID &animated_id);
1539
1547[[nodiscard]] bool unassign_action(OwnedAnimData owned_adt);
1548
1558[[nodiscard]] bool generic_assign_action(ID &animated_id,
1559 bAction *action_to_assign,
1560 bAction *&action_ptr_ref,
1561 slot_handle_t &slot_handle_ref,
1562 char *slot_identifier);
1563
1573[[nodiscard]] ActionSlotAssignmentResult generic_assign_action_slot(Slot *slot_to_assign,
1574 ID &animated_id,
1575 bAction *&action_ptr_ref,
1576 slot_handle_t &slot_handle_ref,
1577 char *slot_identifier);
1578
1589 slot_handle_t slot_handle_to_assign,
1590 ID &animated_id,
1591 bAction *&action_ptr_ref,
1592 slot_handle_t &slot_handle_ref,
1593 char *slot_identifier);
1594
1608[[nodiscard]] Slot *generic_slot_for_autoassign(const ID &animated_id,
1609 Action &action,
1610 StringRefNull last_slot_identifier);
1611
1612/* --------------- Accessors --------------------- */
1613
1617Action *get_action(ID &animated_id);
1618
1628std::optional<std::pair<Action *, Slot *>> get_action_slot_pair(ID &animated_id);
1629
1631 slot_handle_t slot_handle);
1633
1651
1664Channelbag &action_channelbag_ensure(bAction &dna_action, ID &animated_id);
1665
1685 bAction &action,
1686 ID &animated_id,
1687 const FCurveDescriptor &fcurve_descriptor);
1688
1715 bAction *act,
1716 const char group[],
1717 PointerRNA *ptr,
1718 const FCurveDescriptor &fcurve_descriptor);
1719
1730 bAction *act,
1731 const char group[],
1732 PointerRNA *ptr,
1733 const FCurveDescriptor &fcurve_descriptor);
1734
1743FCurve *fcurve_find_in_action(bAction *act, const FCurveDescriptor &fcurve_descriptor);
1744
1751 slot_handle_t slot_handle,
1752 const FCurveDescriptor &fcurve_descriptor);
1753
1759FCurve *fcurve_find_in_assigned_slot(AnimData &adt, const FCurveDescriptor &fcurve_descriptor);
1760
1769bool fcurve_matches_collection_path(const FCurve &fcurve,
1770 StringRefNull collection_rna_path,
1771 StringRefNull data_name);
1772
1781 bAction *act, slot_handle_t slot_handle, FunctionRef<bool(const FCurve &fcurve)> predicate);
1782
1787 FunctionRef<bool(const FCurve &fcurve)> predicate);
1788
1794 FunctionRef<bool(const FCurve &fcurve)> predicate);
1795
1806bool action_fcurve_remove(Action &action, FCurve &fcu);
1807
1822bool action_fcurve_detach(Action &action, FCurve &fcurve_to_detach);
1823
1836void action_fcurve_attach(Action &action,
1837 slot_handle_t action_slot,
1838 FCurve &fcurve_to_attach,
1839 std::optional<StringRefNull> group_name);
1840
1858void action_fcurve_move(Action &action_dst,
1859 slot_handle_t action_slot_dst,
1860 Action &action_src,
1861 FCurve &fcurve);
1862
1877void channelbag_fcurves_move(Channelbag &channelbag_dst, Channelbag &channelbag_src);
1878
1909 Action &action,
1910 slot_handle_t slot_handle,
1911 ID *primary_id);
1912
1925ID *action_slot_get_id_best_guess(Main &bmain, Slot &slot, ID *primary_id);
1926
1939slot_handle_t first_slot_handle(const ::bAction &dna_action);
1940
1966void assert_baklava_phase_1_invariants(const Action &action);
1970void assert_baklava_phase_1_invariants(const Strip &strip);
1971
1976Action *convert_to_layered_action(Main &bmain, const Action &legacy_action);
1977
1987void move_slot(Main &bmain, Slot &slot, Action &from_action, Action &to_action);
1988
1996Slot &duplicate_slot(Action &action, const Slot &slot);
1997
2002
2006void action_deselect_keys(Action &action);
2007
2008} // namespace blender::animrig
2009
2010/* Wrap functions for the DNA structs. */
2011
2012inline blender::animrig::ChannelGroup &bActionGroup::wrap()
2013{
2014 return *reinterpret_cast<blender::animrig::ChannelGroup *>(this);
2015}
2016inline const blender::animrig::ChannelGroup &bActionGroup::wrap() const
2017{
2018 return *reinterpret_cast<const blender::animrig::ChannelGroup *>(this);
2019}
2020
2021inline blender::animrig::Action &bAction::wrap()
2022{
2023 return *reinterpret_cast<blender::animrig::Action *>(this);
2024}
2025inline const blender::animrig::Action &bAction::wrap() const
2026{
2027 return *reinterpret_cast<const blender::animrig::Action *>(this);
2028}
2029
2030inline blender::animrig::Layer &ActionLayer::wrap()
2031{
2032 return *reinterpret_cast<blender::animrig::Layer *>(this);
2033}
2034inline const blender::animrig::Layer &ActionLayer::wrap() const
2035{
2036 return *reinterpret_cast<const blender::animrig::Layer *>(this);
2037}
2038
2039inline blender::animrig::Slot &ActionSlot::wrap()
2040{
2041 return *reinterpret_cast<blender::animrig::Slot *>(this);
2042}
2043inline const blender::animrig::Slot &ActionSlot::wrap() const
2044{
2045 return *reinterpret_cast<const blender::animrig::Slot *>(this);
2046}
2047
2048inline blender::animrig::Strip &ActionStrip::wrap()
2049{
2050 return *reinterpret_cast<blender::animrig::Strip *>(this);
2051}
2052inline const blender::animrig::Strip &ActionStrip::wrap() const
2053{
2054 return *reinterpret_cast<const blender::animrig::Strip *>(this);
2055}
2056
2057inline blender::animrig::StripKeyframeData &ActionStripKeyframeData::wrap()
2058{
2059 return *reinterpret_cast<blender::animrig::StripKeyframeData *>(this);
2060}
2061inline const blender::animrig::StripKeyframeData &ActionStripKeyframeData::wrap() const
2062{
2063 return *reinterpret_cast<const blender::animrig::StripKeyframeData *>(this);
2064}
2065
2066inline blender::animrig::Channelbag &ActionChannelbag::wrap()
2067{
2068 return *reinterpret_cast<blender::animrig::Channelbag *>(this);
2069}
2070inline const blender::animrig::Channelbag &ActionChannelbag::wrap() const
2071{
2072 return *reinterpret_cast<const blender::animrig::Channelbag *>(this);
2073}
Functions to modify FCurves.
Functions to insert, delete or modify keyframes.
Blender kernel action and pose functionality.
#define ATTR_WARN_UNUSED_RESULT
#define ENUM_OPERATORS(_type, _max)
#define MAX_ID_NAME
Definition DNA_ID.h:373
ID_Type
eInsertKeyFlags
@ INSERTKEY_NOFLAGS
long long int int64_t
static btMatrix3x3 Add(const btMatrix3x3 &a, const btMatrix3x3 &b)
void slot_active_set(slot_handle_t slot_handle)
Slot & slot_add_for_id(const ID &animated_id)
float2 get_frame_range_of_slot(slot_handle_t slot_handle) const ATTR_WARN_UNUSED_RESULT
void slot_display_name_define(Slot &slot, StringRefNull new_display_name)
float2 get_frame_range() const ATTR_WARN_UNUSED_RESULT
bool is_cyclic() const ATTR_WARN_UNUSED_RESULT
int strip_keyframe_data_append(StripKeyframeData *strip_data)
void slot_identifier_propagate(Main &bmain, const Slot &slot)
const Layer * layer(int64_t index) const
void slot_identifier_set(Main &bmain, Slot &slot, StringRefNull new_identifier)
int64_t find_slot_index(const Slot &slot) const
const Slot * slot(int64_t index) const
void slot_idtype_define(Slot &slot, ID_Type idtype)
blender::Span< const Layer * > layers() const
void slot_move_to_index(Slot &slot, int to_slot_index)
bool has_keyframes(slot_handle_t action_slot_handle) const ATTR_WARN_UNUSED_RESULT
void slot_display_name_set(Main &bmain, Slot &slot, StringRefNull new_display_name)
void strip_keyframe_data_remove_if_unused(int index)
int64_t find_layer_index(const Layer &layer) const
Action(const Action &other)=delete
Slot & slot_add_for_id_type(ID_Type idtype)
blender::Span< const Slot * > slots() const
bool layer_remove(Layer &layer_to_remove)
Slot * slot_find_by_identifier(StringRefNull slot_identifier)
float2 get_frame_range_of_keys(bool include_modifiers) const ATTR_WARN_UNUSED_RESULT
void slot_identifier_define(Slot &slot, StringRefNull new_identifier)
bool slot_remove(Slot &slot_to_remove)
Slot * slot_for_handle(slot_handle_t handle)
bool has_single_frame() const ATTR_WARN_UNUSED_RESULT
Span< const StripKeyframeData * > strip_keyframe_data() const
bool is_slot_animated(slot_handle_t slot_handle) const
void slot_setup_for_id(Slot &slot, const ID &animated_id)
Layer & layer_add(std::optional< StringRefNull > name)
bool channel_group_remove(bActionGroup &group)
const FCurve * fcurve(int64_t index) const
void fcurve_remove_by_index(int64_t fcurve_index)
bool fcurve_detach(FCurve &fcurve_to_detach)
void fcurve_move_to_index(FCurve &fcurve, int to_fcurve_index)
bool fcurve_assign_to_channel_group(FCurve &fcurve, bActionGroup &to_group)
bActionGroup & channel_group_create(StringRefNull name)
bool fcurve_remove(FCurve &fcurve_to_remove)
const bActionGroup * channel_group(int64_t index) const
FCurve & fcurve_create(Main *bmain, const FCurveDescriptor &fcurve_descriptor)
const bActionGroup * channel_group_find(StringRef name) const
Vector< FCurve * > fcurve_create_many(Main *bmain, Span< FCurveDescriptor > fcurve_descriptors)
void fcurve_detach_by_index(int64_t fcurve_index)
int channel_group_find_index(const bActionGroup *group) const
FCurve & fcurve_ensure(Main *bmain, const FCurveDescriptor &fcurve_descriptor)
FCurve * fcurve_create_unique(Main *bmain, const FCurveDescriptor &fcurve_descriptor)
const FCurve * fcurve_find(const FCurveDescriptor &fcurve_descriptor) const
blender::Span< const FCurve * > fcurves() const
void channel_group_move_to_index(bActionGroup &group, int to_group_index)
int channel_group_containing_index(int fcurve_array_index)
blender::Span< const bActionGroup * > channel_groups() const
bActionGroup & channel_group_ensure(StringRefNull name)
MixMode mix_mode() const
Layer * duplicate_with_shallow_strip_copies(StringRefNull allocation_name) const
Layer(const Layer &other)=delete
bool is_suitable_for(const ID &animated_id) const
std::string idtype_string() const
static constexpr int identifier_length_min
static constexpr int identifier_length_max
static constexpr slot_handle_t unassigned
StringRefNull identifier_without_prefix() const
const Channelbag * channelbag_for_slot(const Slot &slot) const
int64_t find_channelbag_index(const Channelbag &channelbag) const
void slot_data_remove(slot_handle_t slot_handle)
void slot_data_duplicate(slot_handle_t source_slot_handle, slot_handle_t target_slot_handle)
static constexpr Strip::Type TYPE
Channelbag & channelbag_for_slot_add(const Slot &slot)
SingleKeyingResult keyframe_insert(Main *bmain, const Slot &slot, const FCurveDescriptor &fcurve_descriptor, float2 time_value, const KeyframeSettings &settings, eInsertKeyFlags insert_key_flags=INSERTKEY_NOFLAGS, std::optional< float2 > cycle_range=std::nullopt)
Channelbag & channelbag_for_slot_ensure(const Slot &slot)
blender::Span< const Channelbag * > channelbags() const
bool channelbag_remove(Channelbag &channelbag_to_remove)
const Channelbag * channelbag(int64_t index) const
Strip(const Strip &other)=default
T & data(Action &owning_action)
const T & data(const Action &owning_action) const
static Strip & create(Action &owning_action, const Strip::Type type)
int users
#define active
#define sizeof
#define T
void action_fcurve_attach(Action &action, slot_handle_t action_slot, FCurve &fcurve_to_attach, std::optional< StringRefNull > group_name)
bool action_fcurve_remove(Action &action, FCurve &fcu)
void assert_baklava_phase_1_invariants(const Action &action)
bool fcurve_matches_collection_path(const FCurve &fcurve, StringRefNull collection_rna_path, StringRefNull data_name)
void channelbag_fcurves_move(Channelbag &channelbag_dst, Channelbag &channelbag_src)
Vector< FCurve * > fcurves_in_listbase_filtered(ListBase fcurves, FunctionRef< bool(const FCurve &fcurve)> predicate)
Vector< FCurve * > fcurves_in_action_slot_filtered(bAction *act, slot_handle_t slot_handle, FunctionRef< bool(const FCurve &fcurve)> predicate)
Slot * assign_action_ensure_slot_for_keying(Action &action, ID &animated_id)
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)
void action_deselect_keys(Action &action)
const animrig::Channelbag * channelbag_for_action_slot(const Action &action, slot_handle_t slot_handle)
ActionSlotAssignmentResult assign_tmpaction_and_slot_handle(bAction *action, slot_handle_t slot_handle, OwnedAnimData owned_adt)
slot_handle_t first_slot_handle(const ::bAction &dna_action)
Slot & duplicate_slot(Action &action, const Slot &slot)
Vector< FCurve * > fcurves_in_span_filtered(Span< FCurve * > fcurves, FunctionRef< bool(const FCurve &fcurve)> predicate)
bool generic_assign_action(ID &animated_id, bAction *action_to_assign, bAction *&action_ptr_ref, slot_handle_t &slot_handle_ref, char *slot_identifier)
FCurve * action_fcurve_ensure_legacy(Main *bmain, bAction *act, const char group[], PointerRNA *ptr, const FCurveDescriptor &fcurve_descriptor)
ID * action_slot_get_id_best_guess(Main &bmain, Slot &slot, ID *primary_id)
ActionSlotAssignmentResult generic_assign_action_slot(Slot *slot_to_assign, ID &animated_id, bAction *&action_ptr_ref, slot_handle_t &slot_handle_ref, char *slot_identifier)
ActionSlotAssignmentResult assign_action_and_slot(Action *action, Slot *slot_to_assign, ID &animated_id)
decltype(::ActionSlot::handle) slot_handle_t
bool is_action_assignable_to(const bAction *dna_action, ID_Type id_code)
Channelbag & action_channelbag_ensure(bAction &dna_action, ID &animated_id)
Span< FCurve * > fcurves_for_action_slot(Action &action, slot_handle_t slot_handle)
ID * action_slot_get_id_for_keying(Main &bmain, Action &action, slot_handle_t slot_handle, ID *primary_id)
void deselect_keys_actions(blender::Span< bAction * > actions)
Action * get_action(ID &animated_id)
bool assign_tmpaction(bAction *action, OwnedAnimData owned_adt)
FCurve * action_fcurve_ensure_ex(Main *bmain, bAction *act, const char group[], PointerRNA *ptr, const FCurveDescriptor &fcurve_descriptor)
Action * convert_to_layered_action(Main &bmain, const Action &legacy_action)
bool unassign_action(ID &animated_id)
bool action_fcurve_detach(Action &action, FCurve &fcurve_to_detach)
bool assign_action(bAction *action, ID &animated_id)
FCurve * fcurve_find_in_assigned_slot(AnimData &adt, const FCurveDescriptor &fcurve_descriptor)
std::optional< std::pair< Action *, Slot * > > get_action_slot_pair(ID &animated_id)
FCurve & action_fcurve_ensure(Main *bmain, bAction &action, ID &animated_id, const FCurveDescriptor &fcurve_descriptor)
FCurve * fcurve_find_in_action(bAction *act, const FCurveDescriptor &fcurve_descriptor)
ActionSlotAssignmentResult generic_assign_action_slot_handle(slot_handle_t slot_handle_to_assign, ID &animated_id, bAction *&action_ptr_ref, slot_handle_t &slot_handle_ref, char *slot_identifier)
ActionSlotAssignmentResult assign_action_slot(Slot *slot_to_assign, ID &animated_id)
void move_slot(Main &bmain, Slot &slot, Action &from_action, Action &to_action)
Slot * generic_slot_for_autoassign(const ID &animated_id, Action &action, StringRefNull last_slot_identifier)
FCurve * fcurve_find_in_action_slot(bAction *act, slot_handle_t slot_handle, const FCurveDescriptor &fcurve_descriptor)
VecBase< float, 2 > float2
const char * name
char last_slot_identifier[258]
Definition DNA_ID.h:414
char last_slot_identifier[258]
float frame_start
PointerRNA * ptr
Definition wm_files.cc:4238