Blender V4.3
blender::animrig::Action Class Reference

#include <ANIM_action.hh>

Inherits bAction.

Public Member Functions

 Action ()=default
 
 Action (const Action &other)=delete
 
bool is_empty () const
 
bool is_action_legacy () const
 
bool is_action_layered () const
 
blender::Span< const Layer * > layers () const
 
blender::Span< Layer * > layers ()
 
const Layerlayer (int64_t index) const
 
Layerlayer (int64_t index)
 
Layerlayer_add (std::optional< StringRefNull > name)
 
bool layer_remove (Layer &layer_to_remove)
 
void layer_keystrip_ensure ()
 
blender::Span< const Slot * > slots () const
 
blender::Span< Slot * > slots ()
 
const Slotslot (int64_t index) const
 
Slotslot (int64_t index)
 
Slotslot_for_handle (slot_handle_t handle)
 
const Slotslot_for_handle (slot_handle_t handle) const
 
void slot_name_set (Main &bmain, Slot &slot, StringRefNull new_name)
 
void slot_name_define (Slot &slot, StringRefNull new_name)
 
void slot_name_propagate (Main &bmain, const Slot &slot)
 
Slotslot_find_by_name (StringRefNull slot_name)
 
Slotslot_add ()
 
Slotslot_add_for_id (const ID &animated_id)
 
bool slot_remove (Slot &slot_to_remove)
 
void slot_active_set (slot_handle_t slot_handle)
 
Slotslot_active_get ()
 
Span< const StripKeyframeData * > strip_keyframe_data () const
 
Span< StripKeyframeData * > strip_keyframe_data ()
 
Slotfind_suitable_slot_for (const ID &animated_id)
 
bool is_slot_animated (slot_handle_t slot_handle) const
 
bool has_keyframes (slot_handle_t action_slot_handle) const ATTR_WARN_UNUSED_RESULT
 
bool has_single_frame () const ATTR_WARN_UNUSED_RESULT
 
bool is_cyclic () const ATTR_WARN_UNUSED_RESULT
 
Layerget_layer_for_keyframing ()
 
float2 get_frame_range () const ATTR_WARN_UNUSED_RESULT
 
float2 get_frame_range_of_slot (slot_handle_t slot_handle) const ATTR_WARN_UNUSED_RESULT
 
float2 get_frame_range_of_keys (bool include_modifiers) const ATTR_WARN_UNUSED_RESULT
 
void slot_setup_for_id (Slot &slot, const ID &animated_id)
 

Protected Member Functions

int64_t find_layer_index (const Layer &layer) const
 
int64_t find_slot_index (const Slot &slot) const
 
int strip_keyframe_data_append (StripKeyframeData *strip_data)
 
void strip_keyframe_data_remove_if_unused (int index)
 

Protected Attributes

friend Strip
 
friend Layer
 

Additional Inherited Members

- Public Attributes inherited from bAction
ID id
 
struct ActionLayer ** layer_array
 
int layer_array_num
 
int layer_active_index
 
struct ActionSlot ** slot_array
 
int slot_array_num
 
int32_t last_slot_handle
 
struct ActionStripKeyframeData ** strip_keyframe_data_array
 
int strip_keyframe_data_array_num
 
char _pad0 [4]
 
ListBase curves
 
ListBase chanbase DNA_DEPRECATED
 
ListBase groups
 
ListBase markers
 
int flag
 
int active_marker
 
int idroot
 
char _pad1 [4]
 
float frame_start
 
float frame_end
 
PreviewImagepreview
 

Detailed Description

Container of animation data for one or more animated IDs.

Broadly an Action consists of Layers, each Layer has Strips, and it's the Strips that eventually contain the animation data.

Temporary limitation: each Action can only contain one Layer.

Which sub-set of that data drives the animation of which ID is determined by which Slot is associated with that ID.

Note
This wrapper class for the bAction DNA struct only has functionality for the layered animation data. The legacy F-Curves (in bAction::curves) and their groups (in bAction::groups) are not managed here. To see whether an Action uses this legacy data, or has been converted to the current layered structure, use Action::is_action_legacy() and Action::is_action_layered(). Note that an empty Action is considered valid for both.
See also
AnimData::action
AnimData::slot_handle

Definition at line 68 of file ANIM_action.hh.

Constructor & Destructor Documentation

◆ Action() [1/2]

blender::animrig::Action::Action ( )
default

◆ Action() [2/2]

blender::animrig::Action::Action ( const Action & other)
delete

Copy constructor is deleted, as code should use regular ID library management functions to duplicate this data-block.

Member Function Documentation

◆ find_layer_index()

int64_t blender::animrig::Action::find_layer_index ( const Layer & layer) const
protected

Return the layer's index, or -1 if not found in this Action.

Definition at line 316 of file animrig/intern/action.cc.

References layer(), and layers().

Referenced by layer_remove().

◆ find_slot_index()

int64_t blender::animrig::Action::find_slot_index ( const Slot & slot) const
protected

Return the slot's index, or -1 if not found in this Action.

Definition at line 327 of file animrig/intern/action.cc.

References slot(), and slots().

Referenced by slot_remove().

◆ find_suitable_slot_for()

Slot * blender::animrig::Action::find_suitable_slot_for ( const ID & animated_id)

Find the slot that best matches the animated ID.

If the ID is already animated by this Action, by matching this Action's slots with (in order):

  • animated_id.adt->slot_handle,
  • animated_id.adt->slot_name,
  • animated_id.name.

Note that this is different from #slot_for_id, which does not use the slot name, and only works when this Action is already assigned.

Definition at line 559 of file animrig/intern/action.cc.

References AnimData::action, BKE_animdata_from_id(), blender::animrig::Slot::is_suitable_for(), ID::name, slot(), slot_find_by_name(), slot_for_handle(), AnimData::slot_handle, and AnimData::slot_name.

◆ get_frame_range()

float2 blender::animrig::Action::get_frame_range ( ) const

Retrieve the intended playback frame range of the entire Action.

Returns
a tuple (start frame, end frame). This is either the manually set range (if enabled), or the result of a scan of all F-Curves for their first & last frames.
See also
get_frame_range_of_keys()
get_frame_range_of_slot()

Definition at line 758 of file animrig/intern/action.cc.

References ACT_FRAME_RANGE, blender::animrig::legacy::fcurves_all(), bAction::flag, bAction::frame_end, bAction::frame_start, and blender::animrig::get_frame_range_of_fcurves().

Referenced by BKE_nlastrip_new(), and draw_nla_main_data().

◆ get_frame_range_of_keys()

float2 blender::animrig::Action::get_frame_range_of_keys ( bool include_modifiers) const

Calculate the extents of this Action.

Performs a scan of all F-Curves for their first & last key frames.

Returns
tuple (first key frame, last key frame).

Definition at line 788 of file animrig/intern/action.cc.

References blender::animrig::legacy::fcurves_all(), and blender::animrig::get_frame_range_of_fcurves().

Referenced by blender::animrig::tests::TEST_F().

◆ get_frame_range_of_slot()

float2 blender::animrig::Action::get_frame_range_of_slot ( slot_handle_t slot_handle) const

Retrieve the intended playback frame range of a slot.

Returns
a tuple (start frame, end frame). This is either the manually set range (if enabled) of the Action, or the result of a scan of all F-Curves of the slot for their first & last frames.
See also
get_frame_range()

Definition at line 768 of file animrig/intern/action.cc.

References ACT_FRAME_RANGE, blender::animrig::legacy::fcurves_all(), blender::animrig::fcurves_for_action_slot(), bAction::flag, bAction::frame_end, bAction::frame_start, blender::animrig::get_frame_range_of_fcurves(), and is_action_layered().

◆ get_layer_for_keyframing()

Layer * blender::animrig::Action::get_layer_for_keyframing ( )

Get the layer that should be used for user-level keyframe insertion.

Returns
The layer, or nullptr if no layer exists that can currently be used for keyframing (e.g. all layers are locked, once we've implemented locking).

Definition at line 664 of file animrig/intern/action.cc.

References blender::animrig::assert_baklava_phase_1_invariants(), is_empty(), layer(), and layers().

Referenced by blender::animrig::insert_key_layered_action().

◆ has_keyframes()

bool blender::animrig::Action::has_keyframes ( slot_handle_t action_slot_handle) const

◆ has_single_frame()

bool blender::animrig::Action::has_single_frame ( ) const

Return whether the action has one unique point in time keyed.

This is mostly for the pose library, which will have different behavior depending on whether an Action corresponds to a "pose" (one keyframe) or "animation snippet" (multiple keyframes).

Returns
false when there is no keyframe at all or keys on different points in time, true when exactly one point in time is keyed.

Definition at line 712 of file animrig/intern/action.cc.

References compare_ff(), and blender::animrig::legacy::fcurves_all().

◆ is_action_layered()

◆ is_action_legacy()

bool blender::animrig::Action::is_action_legacy ( ) const

Return whether this is a legacy Action.

  • Animation data is stored in bAction::curves.
  • Evaluated equally for all data-blocks that reference this Action.
  • Slot handle is ignored.
Note
An empty Action is valid as both a legacy and layered Action. Code that only supports layered Actions should assert on is_action_layered().

Definition at line 217 of file animrig/intern/action.cc.

References bAction::layer_array_num, and bAction::slot_array_num.

Referenced by achannel_is_part_of_disconnected_slot(), blender::animrig::action_fcurve_detach(), blender::animrig::legacy::action_fcurves_remove(), action_to_keylist(), blender::animrig::legacy::action_treat_as_legacy(), blender::animrig::animdata_fcurve_delete(), animfilter_act_group(), animfilter_action(), animsys_blend_in_action(), animsys_evaluate_action(), blender::animrig::assert_baklava_phase_1_invariants(), blender::animrig::legacy::assigned_action_has_keyframes(), BKE_animdata_id_is_animated(), blender::deg::DepsgraphRelationBuilder::build_animdata_action_targets(), blender::animrig::legacy::channel_groups_all(), blender::animrig::legacy::channel_groups_for_assigned_slot(), blender::animrig::convert_to_layered_action(), ED_curve_updateAnimPaths(), blender::animrig::fcurve_find_in_action(), blender::animrig::fcurve_find_in_action_slot(), blender::animrig::foreach_fcurve_in_action(), blender::animrig::foreach_fcurve_in_action_slot(), has_keyframes(), merge_actions_selection_exec(), blender::animrig::tests::TEST_F(), blender::animrig::tests::TEST_F(), and updateDuplicateActionConstraintSettings().

◆ is_cyclic()

bool blender::animrig::Action::is_cyclic ( ) const

Returns whether this Action is configured as cyclic.

Definition at line 750 of file animrig/intern/action.cc.

References ACT_CYCLIC, ACT_FRAME_RANGE, and bAction::flag.

Referenced by BKE_nlastrip_new().

◆ is_empty()

◆ is_slot_animated()

bool blender::animrig::Action::is_slot_animated ( slot_handle_t slot_handle) const

Return whether this Action actually has any animation data for the given slot.

See also
has_keyframes()

Definition at line 589 of file animrig/intern/action.cc.

References blender::animrig::fcurves_for_action_slot(), blender::Span< T >::is_empty(), and blender::animrig::Slot::unassigned.

Referenced by BKE_animdata_id_is_animated().

◆ layer() [1/2]

Layer * blender::animrig::Action::layer ( int64_t index)

Definition at line 244 of file animrig/intern/action.cc.

References bAction::layer_array.

◆ layer() [2/2]

◆ layer_add()

◆ layer_keystrip_ensure()

void blender::animrig::Action::layer_keystrip_ensure ( )

Ensure that there is at least one layer with the infinite keyframe strip.

Note
Within the limits of Project Baklava Phase 1, this means that there will be exactly one layer with one keyframe strip on it.

Definition at line 294 of file animrig/intern/action.cc.

References blender::animrig::assert_baklava_phase_1_invariants(), DATA_, is_empty(), layer(), layer_add(), layers(), and blender::animrig::Layer::strips().

Referenced by blender::animrig::action_fcurve_attach(), blender::animrig::action_fcurve_ensure(), blender::animrig::tests::add_fcurve_to_action(), blender::animrig::legacy::channelbag_ensure(), and blender::animrig::insert_key_layered_action().

◆ layer_remove()

bool blender::animrig::Action::layer_remove ( Layer & layer_to_remove)

Remove the layer from this Action.

After this call, the passed reference is no longer valid, as the memory will have been freed. Any strips on the layer will be freed too.

Returns
true when the layer was found & removed, false if it wasn't found.

Definition at line 279 of file animrig/intern/action.cc.

References find_layer_index(), bAction::layer_active_index, bAction::layer_array, bAction::layer_array_num, blender::animrig::layer_ptr_destructor(), and blender::dna::array::remove_index().

◆ layers() [1/2]

blender::Span< Layer * > blender::animrig::Action::layers ( )

Definition at line 235 of file animrig/intern/action.cc.

References bAction::layer_array, and bAction::layer_array_num.

◆ layers() [2/2]

◆ slot() [1/2]

Slot * blender::animrig::Action::slot ( int64_t index)

Definition at line 350 of file animrig/intern/action.cc.

References bAction::slot_array.

◆ slot() [2/2]

◆ slot_active_get()

Slot * blender::animrig::Action::slot_active_get ( )

Get the active Slot.

This requires a linear scan of the slots, to find the one with the 'Active' flag set. Storing this on the Slot itself has the advantage that the 'active' status of a Slot can be determined without requiring access to the owning Action.

As this already does a linear scan for the active slot, the slot is returned as a pointer; obtaining the pointer from a handle would require another linear scan to get the pointer, whereas obtaining the handle from the pointer is a constant operation.

Definition at line 549 of file animrig/intern/action.cc.

References blender::animrig::Slot::is_active(), slot(), and slots().

◆ slot_active_set()

void blender::animrig::Action::slot_active_set ( slot_handle_t slot_handle)

Set the active Slot, ensuring only one Slot is flagged as the Active one.

Parameters
slot_handleif Slot::unassigned, there will not be any active slot. Passing an unknown/invalid slot handle will result in no slot being active.

Definition at line 542 of file animrig/intern/action.cc.

References ActionSlot::handle, blender::animrig::Slot::set_active(), slot(), and slots().

Referenced by click_select_channel_action_slot(), and mouse_action_keys().

◆ slot_add()

◆ slot_add_for_id()

Slot & blender::animrig::Action::slot_add_for_id ( const ID & animated_id)

Create a new slot, named after the given ID, and limited to the ID's type.

Note that this assigns neither this Action nor the new Slot to the ID. This function merely initializes the Slot itself to suitable values to start animating this ID.

Definition at line 501 of file animrig/intern/action.cc.

References GS, ActionSlot::idtype, ID::name, slot(), slot_add(), and slot_name_define().

Referenced by blender::animrig::assign_action_ensure_slot_for_keying(), BKE_animdata_transfer_by_basepath(), blender::bke::greasepencil::convert::AnimDataConvertor::fcurves_convert_finalize(), and slot_new_for_object_exec().

◆ slot_find_by_name()

◆ slot_for_handle() [1/2]

◆ slot_for_handle() [2/2]

const Slot * blender::animrig::Action::slot_for_handle ( slot_handle_t handle) const

◆ slot_name_define()

void blender::animrig::Action::slot_name_define ( Slot & slot,
StringRefNull new_name )

Set the slot name, and ensure it is unique.

Note
This does NOT ensure the first two characters match the ID type of this slot. This is the caller's responsibility.
See also
Action::slot_name_set
Action::slot_name_propagate

Definition at line 414 of file animrig/intern/action.cc.

References BLI_assert_msg, blender::StringRefNull::c_str(), ActionSlot::name, blender::animrig::Slot::name_length_min, size(), slot(), blender::animrig::slot_name_ensure_unique(), and STRNCPY_UTF8.

Referenced by slot_add_for_id(), and slot_name_set().

◆ slot_name_propagate()

void blender::animrig::Action::slot_name_propagate ( Main & bmain,
const Slot & slot )

Update the AnimData::action_slot_name field of any ID that is animated by this Slot.

Should be called after slot_name_define(slot). This is implemented as a separate function due to the need to access bmain, which is available in the RNA on-property-update handler, but not in the RNA property setter.

Definition at line 422 of file animrig/intern/action.cc.

References AnimData::action, BKE_animdata_from_id(), FOREACH_MAIN_LISTBASE_BEGIN, FOREACH_MAIN_LISTBASE_END, FOREACH_MAIN_LISTBASE_ID_BEGIN, FOREACH_MAIN_LISTBASE_ID_END, ActionSlot::handle, bAction::id, id_can_have_animdata(), ActionSlot::name, slot(), AnimData::slot_handle, AnimData::slot_name, and STRNCPY_UTF8.

Referenced by slot_name_set().

◆ slot_name_set()

void blender::animrig::Action::slot_name_set ( Main & bmain,
Slot & slot,
StringRefNull new_name )

Set the slot name, ensure it is unique, and propagate the new name to all data-blocks that use it.

This has to be done on the Action level to ensure each slot has a unique name within the Action.

Note
This does NOT ensure the first two characters match the ID type of this slot. This is the caller's responsibility.
See also
Action::slot_name_define
Action::slot_name_propagate

Definition at line 403 of file animrig/intern/action.cc.

References slot(), slot_name_define(), and slot_name_propagate().

Referenced by convert_action_exec(), and version_legacy_actions_to_layered().

◆ slot_remove()

bool blender::animrig::Action::slot_remove ( Slot & slot_to_remove)

Remove a slot, and ALL animation data that belongs to it.

After this call, the reference is no longer valid as the slot will have been freed.

Note that this does NOT unassign this slot from all its users. When the Action is linked into another file, that other file cannot be updated, and so missing slots are something that has to be handled anyway. Also any new slot on this Action will NOT reuse this slot's handle.

Returns
true when the layer was found & removed, false if it wasn't found.

Definition at line 520 of file animrig/intern/action.cc.

References find_slot_index(), ActionSlot::handle, layers(), blender::dna::array::remove_index(), bAction::slot_array, bAction::slot_array_num, and blender::animrig::slot_ptr_destructor().

Referenced by animchannels_delete_exec(), and blender::animrig::move_slot().

◆ slot_setup_for_id()

void blender::animrig::Action::slot_setup_for_id ( Slot & slot,
const ID & animated_id )

Set the slot's ID type to that of the animated ID, ensure the name prefix is set accordingly, and that the name is unique within the Action.

This is a low-level function, and shouldn't be called directly outside of the generic slot-assignment functions.

Note
This assumes that the slot has no ID type set yet. If it does, it is considered a bug to call this function.

Definition at line 681 of file animrig/intern/action.cc.

References BLI_assert, GS, blender::animrig::Slot::has_idtype(), ActionSlot::idtype, ID::name, and slot().

Referenced by blender::animrig::generic_assign_action_slot().

◆ slots() [1/2]

blender::Span< Slot * > blender::animrig::Action::slots ( )

Definition at line 342 of file animrig/intern/action.cc.

References bAction::slot_array, and bAction::slot_array_num.

◆ slots() [2/2]

◆ strip_keyframe_data() [1/2]

Span< StripKeyframeData * > blender::animrig::Action::strip_keyframe_data ( )

◆ strip_keyframe_data() [2/2]

◆ strip_keyframe_data_append()

int blender::animrig::Action::strip_keyframe_data_append ( StripKeyframeData * strip_data)
protected

Append the given StripKeyframeData item to the action's keyframe data array.

Note: this takes ownership of strip_data.

Returns
The index of the appended item in the array.

Definition at line 599 of file animrig/intern/action.cc.

References BLI_assert, blender::animrig::grow_array_and_append(), bAction::strip_keyframe_data_array, and bAction::strip_keyframe_data_array_num.

Referenced by blender::animrig::Strip::create().

◆ strip_keyframe_data_remove_if_unused()

void blender::animrig::Action::strip_keyframe_data_remove_if_unused ( int index)
protected

Remove the keyframe strip data at index if it is no longer used anywhere in the action.

If the strip data is unused, it is both removed from the array and freed. Otherwise no changes are made and the action remains as-is.

Note: this may alter the indices of some strip data items, due to items shifting around to fill the gap left by the removed item. This method ensures that all indices stored within the action (e.g. in the strips themselves) are properly updated to the new values so that everything is still referencing the same data. However, if any indices are stored outside the action, they will no longer be valid.

Definition at line 609 of file animrig/intern/action.cc.

References BLI_assert, layers(), blender::animrig::shrink_array_and_swap_remove(), bAction::strip_keyframe_data_array, and bAction::strip_keyframe_data_array_num.

Referenced by blender::animrig::Layer::strip_remove().

Member Data Documentation

◆ Layer

friend blender::animrig::Action::Layer
protected

Definition at line 345 of file ANIM_action.hh.

◆ Strip

friend blender::animrig::Action::Strip
protected

Definition at line 344 of file ANIM_action.hh.


The documentation for this class was generated from the following files: