104#ifdef WITH_CXX_GUARDEDALLOC
105 MEM_CXX_CLASS_ALLOC_FUNCS(
"editors:AnimKeylist")
131 for (
size_t index = 0; index < keylist->
column_len; index++) {
132 const bool is_first = (index == 0);
135 const bool is_last = (index == keylist->
column_len - 1);
216 "ED_keylist_prepare_for_direct_access needs to be called before searching.");
225 if (found_column == end) {
237 "ED_keylist_prepare_for_direct_access needs to be called before searching.");
246 if (found_column == end) {
255 "ED_keylist_prepare_for_direct_access needs to be called before searching.");
264 if (found_column == end) {
277 "ED_keylist_prepare_for_direct_access needs to be called before searching.");
288 if (column->
cfra >= frame_range.
max) {
298 "ED_keylist_prepare_for_direct_access needs to be called before accessing array.");
345 r_frame_range->
min = first_column->
cfra;
346 r_frame_range->
max = last_column->
cfra;
362 while (first_column && !(first_column->
sel &
SELECT)) {
363 first_column = first_column->
next;
365 while (last_column && !(last_column->
sel &
SELECT)) {
366 last_column = last_column->
prev;
368 if (!first_column || !last_column || first_column == last_column) {
371 r_frame_range->
min = first_column->
cfra;
372 r_frame_range->
max = last_column->
cfra;
409 if (chain->
prev ==
nullptr && chain->
next ==
nullptr) {
414 const float cur_y = chain->
cur->
vec[1][1];
415 float prev_y = cur_y, next_y = cur_y;
418 prev_y = chain->
prev->
vec[1][1];
421 next_y = chain->
next->
vec[1][1];
425 if (prev_y == cur_y && next_y == cur_y) {
430 if ((prev_y < cur_y && next_y > cur_y) || (prev_y > cur_y && next_y < cur_y)) {
437 const float handle_l = l_bezier ? chain->
cur->
vec[0][1] : cur_y;
438 const float handle_r = r_bezier ? chain->
cur->
vec[2][1] : cur_y;
441 if (prev_y < cur_y || next_y < cur_y) {
442 const bool is_overshoot = (handle_l > cur_y || handle_r > cur_y);
448 if (prev_y > cur_y || next_y > cur_y) {
449 const bool is_overshoot = (handle_l < cur_y || handle_r < cur_y);
639 while (cursor->next && cursor->next->cfra <= cfra) {
640 cursor = cursor->
next;
649 while (cursor->prev && cursor->prev->cfra >= cfra) {
650 cursor = cursor->
prev;
673 const bool walking_direction_front_to_back = cursor->cfra <= cfra;
674 if (walking_direction_front_to_back) {
694 "Modifying AnimKeylist isn't allowed after runtime is initialized "
695 "keylist->key_columns/columns_len will get out of sync with runtime.key_columns.");
706 update_func(nearest, userdata);
725 if (
ELEM(
nullptr, keylist, bezt)) {
729 float cfra = bezt->
cur->
vec[1][0];
736 if (
ELEM(
nullptr, keylist, gpf)) {
747 if (
ELEM(
nullptr, keylist, masklay_shape)) {
751 float cfra = masklay_shape->
frame;
781 if (
IS_EQF(beztn->
vec[1][1], prev->vec[1][1])) {
787 IS_EQF(prev->vec[1][1], prev->vec[2][1]);
810 if (
col->totcurve <= 1 &&
col->totblock == 0) {
815 col->block.conflict |= (
col->block.flag ^ block->
flag);
816 col->block.flag |= block->
flag;
817 col->block.sel |= block->
sel;
829 if (bezt && bezt_len >= 2) {
840 for (
int v = 1;
col !=
nullptr &&
v < bezt_len;
v++, bezt++) {
842 if (
is_cfra_lt(bezt[1].vec[1][0], bezt[0].vec[1][0])) {
852 if (
col->prev !=
nullptr) {
877 for (;
col !=
nullptr;
col =
col->next) {
893 max_curve = std::max(max_curve,
int(
col->totcurve));
901 if (
col->totcurve > 0) {
905 else if (prev_ready !=
nullptr) {
910 col->totcurve = max_curve + 1;
921 return ac !=
nullptr && ac->
next !=
nullptr && ac->
totblock > 0;
938 const int saction_flag,
945 ListBase anim_data = {
nullptr,
nullptr};
959 switch (ale->datatype) {
962 ale->adt,
static_cast<FCurve *
>(ale->data), keylist, saction_flag, range);
972 ale->adt,
static_cast<const GreasePencilLayer *
>(ale->data), keylist, saction_flag);
985 const int saction_flag,
989 ListBase anim_data = {
nullptr,
nullptr};
993 if (sce ==
nullptr) {
999 dummy_chan.
data = sce;
1000 dummy_chan.
id = &sce->
id;
1001 dummy_chan.
adt = sce->
adt;
1004 ac.
data = &dummy_chan;
1024 const int saction_flag,
1028 ListBase anim_data = {
nullptr,
nullptr};
1031 Base dummy_base = {
nullptr};
1033 if (ob ==
nullptr) {
1041 dummy_chan.
data = &dummy_base;
1042 dummy_chan.
id = &ob->
id;
1043 dummy_chan.
adt = ob->
adt;
1046 ac.
data = &dummy_chan;
1065 const int saction_flag)
1067 if (cache_file ==
nullptr) {
1074 dummy_chan.
data = cache_file;
1075 dummy_chan.
id = &cache_file->
id;
1076 dummy_chan.
adt = cache_file->
adt;
1080 ac.
data = &dummy_chan;
1084 ListBase anim_data = {
nullptr,
nullptr};
1092 ale->adt,
static_cast<FCurve *
>(ale->data), keylist, saction_flag, {-FLT_MAX, FLT_MAX});
1100 const int key_index,
1101 const bool do_extremes,
1104 chain.
cur = &fcu->
bezt[key_index];
1108 chain.
prev = (key_index > 0) ? &fcu->
bezt[key_index - 1] :
1111 chain.
next = (key_index + 1 < fcu->
totvert) ? &fcu->
bezt[key_index + 1] :
1120 const int saction_flag,
1142 float left_outside_key_x = -
FLT_MAX;
1143 float right_outside_key_x =
FLT_MAX;
1144 int left_outside_key_index = -1;
1145 int right_outside_key_index = -1;
1150 const float x = fcu->
bezt[
v].
vec[1][0];
1151 if (x < range[0] && x > left_outside_key_x) {
1152 left_outside_key_x =
x;
1153 left_outside_key_index =
v;
1155 if (x > range[1] && x < right_outside_key_x) {
1156 right_outside_key_x =
x;
1157 right_outside_key_index =
v;
1159 if (x < range[0] || x > range[1]) {
1168 if (left_outside_key_index >= 0) {
1175 if (right_outside_key_index >= 0) {
1183 if (index_bounds.
min <= index_bounds.
max) {
1185 keylist, &fcu->
bezt[index_bounds.
min], (index_bounds.
max + 1) - index_bounds.
min);
1196 const int saction_flag,
1204 if (agrp->wrap().is_legacy()) {
1206 if (fcu->grp != agrp) {
1218 for (
FCurve *fcurve : fcurves) {
1227 const int saction_flag,
1231 for (
FCurve *fcurve : fcurves_for_action_slot(action, slot_handle)) {
1239 const int saction_flag,
1265 if (!gpd || !keylist) {
1283 const int saction_flag,
1284 const bool active_layer_only)
1286 if ((grease_pencil ==
nullptr) || (keylist ==
nullptr)) {
1290 if (active_layer_only && grease_pencil->has_active_layer()) {
1306 const Layer &layer = gpl->wrap();
1307 for (
auto item : layer.frames().items()) {
1310 cel.frame = item.value;
1312 float cfra =
float(item.key);
1321 const int saction_flag)
1323 if ((layer_group ==
nullptr) || (keylist ==
nullptr)) {
1329 if (node.is_group()) {
1332 else if (node.is_layer()) {
1340 if (!gpl || !keylist) {
1356 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)
void BLI_addhead(struct ListBase *listbase, void *vlink) ATTR_NONNULL(1)
#define LISTBASE_FOREACH(type, var, list)
#define LISTBASE_FOREACH_BACKWARD(type, var, list)
BLI_INLINE void BLI_listbase_clear(struct ListBase *lb)
void BLI_insertlinkafter(struct ListBase *listbase, void *vprevlink, void *vnewlink) ATTR_NONNULL(1)
#define LISTBASE_FOREACH_INDEX(type, var, list, index_var)
void void BLI_freelistN(struct ListBase *listbase) ATTR_NONNULL(1)
void BLI_insertlinkbefore(struct 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)
size_t ANIM_animdata_filter(bAnimContext *ac, ListBase *anim_data, const eAnimFilter_Flags filter_mode, void *data, const eAnimCont_Types datatype)
ATTR_WARN_UNUSED_RESULT const BMVert * v
bool is_action_legacy() const
blender::Span< const FCurve * > fcurves() const
local_group_size(16, 16) .push_constant(Type b
static bool is_cyclic(const Nurb *nu)
draw_view in_light_buf[] float
BLI_INLINE bool is_cfra_lt(const float a, const float b)
static ActKeyColumn * ED_keylist_find_neighbor_front_to_back(ActKeyColumn *cursor, float cfra)
void mask_to_keylist(bDopeSheet *, MaskLayer *masklay, AnimKeylist *keylist)
BLI_INLINE bool is_cfra_eq(const float a, const float b)
static void keylist_first_last(const AnimKeylist *keylist, const ActKeyColumn **first_column, const ActKeyColumn **last_column)
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)
bool ED_keylist_selected_keys_frame_range(const AnimKeylist *keylist, Range2f *r_frame_range)
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 ED_keylist_reset_last_accessed(AnimKeylist *keylist)
static void nupdate_ak_cel(ActKeyColumn *ak, void *data)
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 ED_keylist_runtime_init_listbase(AnimKeylist *keylist)
const ActKeyColumn * ED_keylist_find_any_between(const AnimKeylist *keylist, const Range2f frame_range)
static void add_gpframe_to_keycolumns_list(AnimKeylist *keylist, bGPDframe *gpf)
static void ED_keylist_runtime_init(AnimKeylist *keylist)
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)
void ED_keylist_prepare_for_direct_access(AnimKeylist *keylist)
void summary_to_keylist(bAnimContext *ac, AnimKeylist *keylist, const int saction_flag, blender::float2 range)
bool ED_keylist_all_keys_frame_range(const AnimKeylist *keylist, Range2f *r_frame_range)
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)
void fcurve_to_keylist(AnimData *adt, FCurve *fcu, AnimKeylist *keylist, const int saction_flag, blender::float2 range)
static eKeyframeExtremeDrawOpts bezt_extreme_type(const BezTripleChain *chain)
static ActKeyColumn * nalloc_ak_bezt(void *data)
static void ED_keylist_convert_key_columns_to_array(AnimKeylist *keylist)
static void ED_keylist_add_or_update_column(AnimKeylist *keylist, float cfra, KeylistCreateColumnFunction create_func, KeylistUpdateColumnFunction update_func, void *userdata)
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)
static void add_masklay_to_keycolumns_list(AnimKeylist *keylist, MaskLayerShape *masklay_shape)
void action_slot_to_keylist(AnimData *adt, animrig::Action &action, const animrig::slot_handle_t slot_handle, AnimKeylist *keylist, const int saction_flag, blender::float2 range)
const ActKeyColumn * ED_keylist_find_next(const AnimKeylist *keylist, const float cfra)
static void ED_keylist_runtime_update_key_column_next_prev(AnimKeylist *keylist)
int64_t ED_keylist_array_len(const AnimKeylist *keylist)
const ListBase * ED_keylist_listbase(const AnimKeylist *keylist)
static const ActKeyColumn * ED_keylist_find_upper_bound(const AnimKeylist *keylist, const float cfra)
bool ED_keylist_is_empty(const AnimKeylist *keylist)
const ActKeyColumn * ED_keylist_find_exact(const AnimKeylist *keylist, const float cfra)
static ActKeyColumn * ED_keylist_find_neighbor_back_to_front(ActKeyColumn *cursor, float cfra)
void grease_pencil_layer_group_to_keylist(AnimData *adt, const GreasePencilLayerTreeGroup *layer_group, AnimKeylist *keylist, const int saction_flag)
static const ActKeyColumn * ED_keylist_find_lower_bound(const AnimKeylist *keylist, const float cfra)
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)
static ActKeyColumn * ED_keylist_find_exact_or_neighbor_column(AnimKeylist *keylist, float cfra)
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)
static PyObject * create_func(PyObject *, PyObject *args)
eBezTriple_KeyframeType key_type
bool is_runtime_initialized
std::optional< ActKeyColumn * > last_accessed_column
struct AnimKeylist::@302 runtime
blender::Array< ActKeyColumn > key_columns
struct ActionChannelBag * channel_bag