105 MEM_CXX_CLASS_ALLOC_FUNCS(
"editors:AnimKeylist")
130 for (
size_t index = 0; index < keylist->
column_len; index++) {
131 const bool is_first = (index == 0);
134 const bool is_last = (index == keylist->
column_len - 1);
213 "ED_keylist_prepare_for_direct_access needs to be called before searching.");
222 if (found_column == end) {
234 "ED_keylist_prepare_for_direct_access needs to be called before searching.");
243 if (found_column == end) {
252 "ED_keylist_prepare_for_direct_access needs to be called before searching.");
261 if (found_column == end) {
273 "ED_keylist_prepare_for_direct_access needs to be called before searching.");
287 "This should exist since we checked for cfra bounds just before");
295 const float prev_delta = cfra - prev->cfra;
296 const float next_delta =
next->cfra - cfra;
299 if (prev_delta <= next_delta) {
309 "ED_keylist_prepare_for_direct_access needs to be called before searching.");
320 if (column->
cfra >= frame_range.
max) {
330 "ED_keylist_prepare_for_direct_access needs to be called before accessing array.");
377 r_frame_range->
min = first_column->
cfra;
378 r_frame_range->
max = last_column->
cfra;
394 while (first_column && !(first_column->
sel &
SELECT)) {
395 first_column = first_column->
next;
397 while (last_column && !(last_column->
sel &
SELECT)) {
398 last_column = last_column->
prev;
400 if (!first_column || !last_column || first_column == last_column) {
403 r_frame_range->
min = first_column->
cfra;
404 r_frame_range->
max = last_column->
cfra;
441 if (chain->
prev ==
nullptr && chain->
next ==
nullptr) {
446 const float cur_y = chain->
cur->
vec[1][1];
447 float prev_y = cur_y, next_y = cur_y;
450 prev_y = chain->
prev->
vec[1][1];
453 next_y = chain->
next->
vec[1][1];
457 if (prev_y == cur_y && next_y == cur_y) {
462 if ((prev_y < cur_y && next_y > cur_y) || (prev_y > cur_y && next_y < cur_y)) {
469 const float handle_l = l_bezier ? chain->
cur->
vec[0][1] : cur_y;
470 const float handle_r = r_bezier ? chain->
cur->
vec[2][1] : cur_y;
473 if (prev_y < cur_y || next_y < cur_y) {
474 const bool is_overshoot = (handle_l > cur_y || handle_r > cur_y);
480 if (prev_y > cur_y || next_y > cur_y) {
481 const bool is_overshoot = (handle_l < cur_y || handle_r < cur_y);
647 ak->
key_type = eBezTriple_KeyframeType::BEZT_KEYTYPE_KEYFRAME;
712 cursor = cursor->
next;
722 cursor = cursor->
prev;
745 const bool walking_direction_front_to_back = cursor->
cfra <= cfra;
746 if (walking_direction_front_to_back) {
766 "Modifying AnimKeylist isn't allowed after runtime is initialized "
767 "keylist->key_columns/columns_len will get out of sync with runtime.key_columns.");
778 update_func(nearest, userdata);
797 if (
ELEM(
nullptr, keylist, bezt)) {
801 float cfra = bezt->
cur->
vec[1][0];
808 if (
ELEM(
nullptr, keylist, gpf)) {
819 if (
ELEM(
nullptr, keylist, masklay_shape)) {
823 float cfra = masklay_shape->
frame;
853 if (
IS_EQF(beztn->
vec[1][1], prev->vec[1][1])) {
859 IS_EQF(prev->vec[1][1], prev->vec[2][1]);
882 if (
col->totcurve <= 1 &&
col->totblock == 0) {
887 col->block.conflict |= (
col->block.flag ^ block->
flag);
888 col->block.flag |= block->
flag;
889 col->block.sel |= block->
sel;
901 if (bezt && bezt_len >= 2) {
912 for (
int v = 1;
col !=
nullptr &&
v < bezt_len;
v++, bezt++) {
914 if (
is_cfra_lt(bezt[1].vec[1][0], bezt[0].vec[1][0])) {
924 if (
col->prev !=
nullptr) {
949 for (;
col !=
nullptr;
col =
col->next) {
965 max_curve = std::max(max_curve,
int(
col->totcurve));
973 if (
col->totcurve > 0) {
977 else if (prev_ready !=
nullptr) {
982 col->totcurve = max_curve + 1;
993 return ac !=
nullptr && ac->
next !=
nullptr && ac->
totblock > 0;
1010 const int saction_flag,
1017 ListBase anim_data = {
nullptr,
nullptr};
1030 switch (ale->datatype) {
1033 static_cast<FCurve *
>(ale->data),
1047 ale->adt,
static_cast<const GreasePencilLayer *
>(ale->data), keylist, saction_flag);
1062 const int saction_flag,
1086 ListBase anim_data = {
nullptr,
nullptr};
1099 static_cast<FCurve *
>(ale->data),
1112 const int saction_flag,
1116 ListBase anim_data = {
nullptr,
nullptr};
1120 if (sce ==
nullptr) {
1126 dummy_chan.
data = sce;
1127 dummy_chan.
id = &sce->
id;
1128 dummy_chan.
adt = sce->
adt;
1131 ac.
data = &dummy_chan;
1144 static_cast<FCurve *
>(ale->data),
1157 const int saction_flag,
1161 ListBase anim_data = {
nullptr,
nullptr};
1164 Base dummy_base = {
nullptr};
1166 if (ob ==
nullptr) {
1174 dummy_chan.
data = &dummy_base;
1175 dummy_chan.
id = &ob->
id;
1176 dummy_chan.
adt = ob->
adt;
1179 ac.
data = &dummy_chan;
1191 static_cast<FCurve *
>(ale->data),
1204 const int saction_flag)
1206 if (cache_file ==
nullptr) {
1213 dummy_chan.
data = cache_file;
1214 dummy_chan.
id = &cache_file->
id;
1215 dummy_chan.
adt = cache_file->
adt;
1219 ac.
data = &dummy_chan;
1225 ListBase anim_data = {
nullptr,
nullptr};
1232 static_cast<FCurve *
>(ale->data),
1235 {-FLT_MAX, FLT_MAX},
1244 const int key_index,
1245 const bool do_extremes,
1248 chain.
cur = &fcu->
bezt[key_index];
1252 chain.
prev = (key_index > 0) ? &fcu->
bezt[key_index - 1] :
1255 chain.
next = (key_index + 1 < fcu->
totvert) ? &fcu->
bezt[key_index + 1] :
1264 const int saction_flag,
1266 const bool use_nla_remapping)
1273 "Cannot perform NLA time remapping without an adt.");
1280 if (use_nla_remapping) {
1294 float left_outside_key_x = -
FLT_MAX;
1295 float right_outside_key_x =
FLT_MAX;
1296 int left_outside_key_index = -1;
1297 int right_outside_key_index = -1;
1303 if (
x < range[0] &&
x > left_outside_key_x) {
1304 left_outside_key_x =
x;
1305 left_outside_key_index =
v;
1307 if (
x > range[1] &&
x < right_outside_key_x) {
1308 right_outside_key_x =
x;
1309 right_outside_key_index =
v;
1311 if (
x < range[0] ||
x > range[1]) {
1320 if (left_outside_key_index >= 0) {
1327 if (right_outside_key_index >= 0) {
1335 if (index_bounds.
min <= index_bounds.
max) {
1337 keylist, &fcu->
bezt[index_bounds.
min], (index_bounds.
max + 1) - index_bounds.
min);
1340 if (use_nla_remapping) {
1348 const int saction_flag,
1356 if (agrp->wrap().is_legacy()) {
1358 if (fcu->grp != agrp) {
1370 for (
FCurve *fcurve : fcurves) {
1378 const int saction_flag,
1407 if (!gpd || !keylist) {
1425 const int saction_flag,
1426 const bool active_layer_only)
1428 if ((grease_pencil ==
nullptr) || (keylist ==
nullptr)) {
1432 if (active_layer_only && grease_pencil->has_active_layer()) {
1448 const Layer &layer = gpl->wrap();
1452 cel.
frame = item.value;
1454 float cfra =
float(item.key);
1463 const int saction_flag)
1465 if ((layer_group ==
nullptr) || (keylist ==
nullptr)) {
1482 if (!gpl || !keylist) {
1498 if (!masklay || !keylist) {
Functions and classes to work with Actions.
bool BKE_fcurve_is_cyclic(const FCurve *fcu)
#define BEZT_BINARYSEARCH_THRESH
Low-level operations for grease pencil.
#define BLI_assert_msg(a, msg)
#define LISTBASE_FOREACH(type, var, list)
BLI_INLINE void BLI_listbase_clear(ListBase *lb)
#define LISTBASE_FOREACH_BACKWARD(type, var, list)
void void BLI_freelistN(ListBase *listbase) ATTR_NONNULL(1)
#define LISTBASE_FOREACH_INDEX(type, var, list, index_var)
void BLI_insertlinkafter(ListBase *listbase, void *vprevlink, void *vnewlink) ATTR_NONNULL(1)
void BLI_addhead(ListBase *listbase, void *vlink) ATTR_NONNULL(1)
void BLI_insertlinkbefore(ListBase *listbase, void *vnextlink, void *vnewlink) ATTR_NONNULL(1)
#define BEZT_ISSEL_ANY(bezt)
Object is a sort of wrapper for general info.
@ ANIMFILTER_DATA_VISIBLE
@ ACTKEYBLOCK_FLAG_ANY_HOLD
@ ACTKEYBLOCK_FLAG_MOVING_HOLD
@ ACTKEYBLOCK_FLAG_GPENCIL
@ ACTKEYBLOCK_FLAG_NON_BEZIER
@ ACTKEYBLOCK_FLAG_STATIC_HOLD
@ KEYFRAME_HANDLE_AUTO_CLAMP
@ KEYFRAME_HANDLE_ALIGNED
Read Guarded memory(de)allocation.
void ANIM_animdata_freelist(ListBase *anim_data)
void ANIM_nla_mapping_apply_fcurve(AnimData *adt, FCurve *fcu, bool restore, bool only_keys)
bool ANIM_nla_mapping_allowed(const bAnimListElem *ale)
size_t ANIM_animfilter_action_slot(bAnimContext *ac, ListBase *anim_data, animrig::Action &action, animrig::Slot &slot, const eAnimFilter_Flags filter_mode, ID *animated_id)
size_t ANIM_animdata_filter(bAnimContext *ac, ListBase *anim_data, const eAnimFilter_Flags filter_mode, void *data, const eAnimCont_Types datatype)
BMesh const char void * data
ATTR_WARN_UNUSED_RESULT const BMVert * v
ItemIterator items() const &
bool is_action_legacy() const
Slot * slot_for_handle(slot_handle_t handle)
blender::Span< const FCurve * > fcurves() const
const Map< FramesMapKeyT, GreasePencilFrame > & frames() const
const LayerGroup & as_group() const
const Layer & as_layer() const
static bool is_cyclic(const Nurb *nu)
static ActKeyColumn * keylist_find_neighbor_back_to_front(ActKeyColumn *cursor, float cfra)
BLI_INLINE bool is_cfra_lt(const float a, const float b)
void mask_to_keylist(bDopeSheet *, MaskLayer *masklay, AnimKeylist *keylist)
BLI_INLINE bool is_cfra_eq(const float a, const float b)
static void keylist_convert_key_columns_to_array(AnimKeylist *keylist)
static ActKeyColumn * nalloc_ak_seqframe(void *data)
static void keylist_first_last(const AnimKeylist *keylist, const ActKeyColumn **first_column, const ActKeyColumn **last_column)
static void keylist_reset_last_accessed(AnimKeylist *keylist)
const ActKeyColumn * ED_keylist_find_prev(const AnimKeylist *keylist, const float cfra)
static eKeyframeHandleDrawOpts bezt_handle_type(const BezTriple *bezt)
static ActKeyColumn * nalloc_ak_cel(void *data)
bool actkeyblock_is_valid(const ActKeyColumn *ac)
static void nupdate_ak_gpframe(ActKeyColumn *ak, void *data)
void action_slot_summary_to_keylist(bAnimContext *ac, ID *animated_id, animrig::Action &action, const animrig::slot_handle_t slot_handle, AnimKeylist *keylist, const int saction_flag, blender::float2 range)
static ActKeyColumn * keylist_find_neighbor_front_to_back(ActKeyColumn *cursor, float cfra)
const ActKeyColumn * ED_keylist_find_any_between(const AnimKeylist *keylist, const Bounds< float > frame_range)
void fcurve_to_keylist(AnimData *adt, FCurve *fcu, AnimKeylist *keylist, const int saction_flag, blender::float2 range, const bool use_nla_remapping)
std::function< ActKeyColumn *(void *userdata)> KeylistCreateColumnFunction
std::function< void(ActKeyColumn *, void *)> KeylistUpdateColumnFunction
void gpencil_to_keylist(bDopeSheet *ads, bGPdata *gpd, AnimKeylist *keylist, const bool active)
static ActKeyColumn * nalloc_ak_masklayshape(void *data)
static void nupdate_ak_cel(ActKeyColumn *ak, void *data)
static void keylist_runtime_init(AnimKeylist *keylist)
static void nupdate_ak_masklayshape(ActKeyColumn *ak, void *data)
void scene_to_keylist(bDopeSheet *ads, Scene *sce, AnimKeylist *keylist, const int saction_flag, blender::float2 range)
static ActKeyColumn * nalloc_ak_gpframe(void *data)
static void add_gpframe_to_keycolumns_list(AnimKeylist *keylist, bGPDframe *gpf)
void ob_to_keylist(bDopeSheet *ads, Object *ob, AnimKeylist *keylist, const int saction_flag, blender::float2 range)
void cachefile_to_keylist(bDopeSheet *ads, CacheFile *cache_file, AnimKeylist *keylist, const int saction_flag)
void grease_pencil_data_block_to_keylist(AnimData *adt, const GreasePencil *grease_pencil, AnimKeylist *keylist, const int saction_flag, const bool active_layer_only)
static void nupdate_ak_bezt(ActKeyColumn *ak, void *data)
const ActKeyColumn * ED_keylist_find_closest(const AnimKeylist *keylist, const float cfra)
void ED_keylist_prepare_for_direct_access(AnimKeylist *keylist)
static void keylist_runtime_update_key_column_next_prev(AnimKeylist *keylist)
bool ED_keylist_all_keys_frame_range(const AnimKeylist *keylist, Bounds< float > *r_frame_range)
void summary_to_keylist(bAnimContext *ac, AnimKeylist *keylist, const int saction_flag, blender::float2 range)
static void keylist_runtime_init_listbase(AnimKeylist *keylist)
static const ActKeyColumn * keylist_find_upper_bound(const AnimKeylist *keylist, const float cfra)
static void compute_keyblock_data(ActKeyBlockInfo *info, const BezTriple *prev, const BezTriple *beztn)
static void add_keyblock_info(ActKeyColumn *col, const ActKeyBlockInfo *block)
AnimKeylist * ED_keylist_create()
static const ActKeyBlockInfo dummy_keyblock
int actkeyblock_get_valid_hold(const ActKeyColumn *ac)
static void set_up_beztriple_chain(BezTripleChain &chain, const FCurve *fcu, const int key_index, const bool do_extremes, const bool is_cyclic)
void ED_keylist_free(AnimKeylist *keylist)
static ActKeyColumn * keylist_find_exact_or_neighbor_column(AnimKeylist *keylist, float cfra)
void sequencer_strip_to_keylist(const Strip &strip, AnimKeylist &keylist, Scene &scene)
static eKeyframeExtremeDrawOpts bezt_extreme_type(const BezTripleChain *chain)
static void nupdate_ak_seqframe(ActKeyColumn *ak, void *data)
static ActKeyColumn * nalloc_ak_bezt(void *data)
static void add_bezt_to_keyblocks_list(AnimKeylist *keylist, BezTriple *bezt, const int bezt_len)
static void update_keyblocks(AnimKeylist *keylist, BezTriple *bezt, const int bezt_len)
bool ED_keylist_selected_keys_frame_range(const AnimKeylist *keylist, Bounds< float > *r_frame_range)
static void add_masklay_to_keycolumns_list(AnimKeylist *keylist, MaskLayerShape *masklay_shape)
const ActKeyColumn * ED_keylist_find_next(const AnimKeylist *keylist, const float cfra)
static void keylist_add_or_update_column(AnimKeylist *keylist, float cfra, KeylistCreateColumnFunction create_func, KeylistUpdateColumnFunction update_func, void *userdata)
static const ActKeyColumn * keylist_find_lower_bound(const AnimKeylist *keylist, const float cfra)
int64_t ED_keylist_array_len(const AnimKeylist *keylist)
const ListBase * ED_keylist_listbase(const AnimKeylist *keylist)
bool ED_keylist_is_empty(const AnimKeylist *keylist)
const ActKeyColumn * ED_keylist_find_exact(const AnimKeylist *keylist, const float cfra)
void grease_pencil_layer_group_to_keylist(AnimData *adt, const GreasePencilLayerTreeGroup *layer_group, AnimKeylist *keylist, const int saction_flag)
static void add_bezt_to_keycolumns_list(AnimKeylist *keylist, BezTripleChain *bezt)
void action_to_keylist(AnimData *adt, bAction *dna_action, AnimKeylist *keylist, const int saction_flag, blender::float2 range)
void grease_pencil_cels_to_keylist(AnimData *, const GreasePencilLayer *gpl, AnimKeylist *keylist, int)
void gpl_to_keylist(bDopeSheet *, bGPDlayer *gpl, AnimKeylist *keylist)
void action_group_to_keylist(AnimData *adt, bActionGroup *agrp, AnimKeylist *keylist, const int saction_flag, blender::float2 range)
const ActKeyColumn * ED_keylist_array(const AnimKeylist *keylist)
void * MEM_callocN(size_t len, const char *str)
decltype(::ActionSlot::handle) slot_handle_t
T min(const T &a, const T &b)
void min_max(const T &value, T &min, T &max)
T max(const T &a, const T &b)
int retiming_key_timeline_frame_get(const Scene *scene, const Strip *strip, const SeqRetimingKey *key)
MutableSpan< SeqRetimingKey > retiming_keys_get(const Strip *strip)
bool retiming_is_active(const Strip *strip)
VecBase< float, 2 > float2
static PyObject * create_func(PyObject *, PyObject *args)
eBezTriple_KeyframeType key_type
struct AnimKeylist::@177352003075216107275373003375205053134051274013 runtime
bool is_runtime_initialized
std::optional< ActKeyColumn * > last_accessed_column
const SeqRetimingKey * key
struct ActionChannelbag * channelbag
eDopeSheet_FilterFlag flag
struct bAnimContext::@242276144047124000362312251357014355232301013033 filters
eDopeSheet_FilterFlag2 flag2