From 574f15d1f5e0c9f1eed30e255a4005d0157772dd Mon Sep 17 00:00:00 2001 From: Nate Rupsis Date: Mon, 3 Apr 2023 15:53:51 -0400 Subject: [PATCH 1/6] Cleanup: Fix spelling for 'bone' --- source/blender/editors/transform/transform_orientations.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/blender/editors/transform/transform_orientations.c b/source/blender/editors/transform/transform_orientations.c index f1e83c5090c..3853a2ae1cf 100644 --- a/source/blender/editors/transform/transform_orientations.c +++ b/source/blender/editors/transform/transform_orientations.c @@ -621,7 +621,7 @@ short ED_transform_calc_orientation_from_type_ex(const Scene *scene, if (ob) { if (ob->mode & OB_MODE_POSE) { /* Each bone moves on its own local axis, but to avoid confusion, - * use the active pones axis for display #33575, this works as expected on a single + * use the active bone's axis for display #33575, this works as expected on a single * bone and users who select many bones will understand what's going on and what local * means when they start transforming. */ ED_getTransformOrientationMatrix(scene, view_layer, v3d, ob, obedit, pivot_point, r_mat); -- 2.30.2 From 111a3c8d6293b6c2d4009a6d25b9d7c5536c0182 Mon Sep 17 00:00:00 2001 From: Nate Rupsis Date: Tue, 4 Apr 2023 16:31:05 -0400 Subject: [PATCH 2/6] initial vertical shuffle code --- .../editors/transform/transform_convert_nla.c | 269 +++++++++++++++--- source/blender/makesdna/DNA_anim_types.h | 5 + 2 files changed, 236 insertions(+), 38 deletions(-) diff --git a/source/blender/editors/transform/transform_convert_nla.c b/source/blender/editors/transform/transform_convert_nla.c index aefcf26c49f..4eeefe313a3 100644 --- a/source/blender/editors/transform/transform_convert_nla.c +++ b/source/blender/editors/transform/transform_convert_nla.c @@ -54,6 +54,12 @@ typedef struct TransDataNla { /** index of track that strip is currently in. */ int trackIndex; + + // TODO go over this comment + /** NOTE: This index is relative to the initial first track at the start of transforming and + * thus can be negative when the tracks list grows downward. */ + int signed_track_index; + /** handle-index: 0 for dummy entry, -1 for start, 1 for end, 2 for both ends. */ int handle; } TransDataNla; @@ -135,7 +141,94 @@ static float transdata_get_time_shuffle_offset(ListBase *trans_datas) BLI_assert(offset_left <= 0); BLI_assert(offset_right >= 0); - return -offset_left < offset_right ? offset_left : offset_right; + return fabs(offset_left) < offset_right ? offset_left : offset_right; +} + +// TODO go over these comments +/** Assumes all of given trans_datas are part of the same ID. + * + * \param r_total_offset: The minimal total signed offset that results in valid strip track-moves + * for all strips from \a trans_datas. + * + * \returns true if \a r_total_offset results in a valid offset, false if no solution exists in the + * desired direction. + */ +static bool transdata_get_track_shuffle_offset_side(ListBase *trans_datas, + const bool shuffle_down, + int *r_total_offset) +{ + *r_total_offset = 0; + if (BLI_listbase_is_empty(trans_datas)) { + return false; + } + + ListBase *tracks = &BKE_animdata_from_id( + ((TransDataNla *)((LinkData *)trans_datas->first)->data)->id) + ->nla_tracks; + + int offset; + do { + offset = 0; + + LISTBASE_FOREACH (LinkData *, link, trans_datas) { + TransDataNla *trans_data = (TransDataNla *)link->data; + + NlaTrack *dst_track = BLI_findlink(tracks, trans_data->trackIndex + *r_total_offset); + + /* Cannot keep moving strip in given track direction. No solution. */ + if (dst_track == NULL) { + return false; + } + + /* Shuffle only if track is locked or library override. */ + if (((dst_track->flag & NLATRACK_PROTECTED) == 0) && + !BKE_nlatrack_is_nonlocal_in_liboverride(trans_data->id, dst_track)) { + continue; + } + + offset = shuffle_down ? 1 : -1; + break; + } + + *r_total_offset += offset; + } while (offset != 0); + + return true; +} + +// TODO go over these comments +/** Assumes all of given trans_datas are part of the same ID. + * + * \param r_track_offset: The minimal total signed offset that results in valid strip track-moves + * for all strips from \a trans_datas. + * + * \returns true if \a r_track_offset results in a valid offset, false if no solution exists in + * either direction. + */ +static bool transdata_get_track_shuffle_offset(ListBase *trans_datas, int *r_track_offset) +{ + int offset_down = 0; + const bool down_valid = transdata_get_track_shuffle_offset_side(trans_datas, true, &offset_down); + + int offset_up = 0; + const bool up_valid = transdata_get_track_shuffle_offset_side(trans_datas, false, &offset_up); + + if (down_valid && up_valid) { + if (abs(offset_down) < offset_up) { + *r_track_offset = offset_down; + } + else { + *r_track_offset = offset_up; + } + } + else if (down_valid) { + *r_track_offset = offset_down; + } + else if (up_valid) { + *r_track_offset = offset_up; + } + + return down_valid || up_valid; } /* -------------------------------------------------------------------- */ @@ -396,6 +489,7 @@ static void createTransNlaData(bContext *C, TransInfo *t) tdn->oldTrack = tdn->nlt = nlt; tdn->strip = strip; tdn->trackIndex = BLI_findindex(&adt->nla_tracks, nlt); + tdn->signed_track_index = tdn->trackIndex; yval = (float)(tdn->trackIndex * NLACHANNEL_STEP(snla)); @@ -577,54 +671,78 @@ static void recalcData_nla(TransInfo *t) continue; } - delta_y1 = ((int)tdn->h1[1] / NLACHANNEL_STEP(snla) - tdn->trackIndex); - delta_y2 = ((int)tdn->h2[1] / NLACHANNEL_STEP(snla) - tdn->trackIndex); + delta_y1 = ((int)tdn->h1[1] / NLACHANNEL_STEP(snla) - tdn->signed_track_index); + delta_y2 = ((int)tdn->h2[1] / NLACHANNEL_STEP(snla) - tdn->signed_track_index); + /* Move strip into track in the requested direction. */ if (delta_y1 || delta_y2) { - NlaTrack *track; int delta = (delta_y2) ? delta_y2 : delta_y1; - int n; - /* Move in the requested direction, - * checking at each layer if there's space for strip to pass through, - * stopping on the last track available or that we're able to fit in. + AnimData *anim_data = BKE_animdata_from_id(tdn->id); + ListBase *nla_tracks = &anim_data->nla_tracks; + + NlaTrack *old_track = tdn->nlt; + NlaTrack *dst_track = NULL; + + /* Calculate the total new tracks needed + * + * Determine dst_track, which will end up being NULL, the last library override + * track, or a normal local track. The first two cases lead to delta_new_tracks!=0. + * The last case leads to delta_new_tracks==0. */ - if (delta > 0) { - for (track = tdn->nlt->next, n = 0; (track) && (n < delta); track = track->next, n++) { - /* check if space in this track for the strip */ - if (BKE_nlatrack_has_space(track, strip->start, strip->end) && - !BKE_nlatrack_is_nonlocal_in_liboverride(tdn->id, track)) { - /* move strip to this track */ - BKE_nlatrack_remove_strip(tdn->nlt, strip); - BKE_nlatrack_add_strip(track, strip, is_liboverride); - tdn->nlt = track; - tdn->trackIndex++; - } - else { /* can't move any further */ - break; - } + int delta_new_tracks = delta; + dst_track = old_track; + + while (delta_new_tracks < 0) { + dst_track = dst_track->prev; + if (dst_track == NULL || BKE_nlatrack_is_nonlocal_in_liboverride(tdn->id, dst_track)) { + break; } + delta_new_tracks++; } - else { - /* make delta 'positive' before using it, since we now know to go backwards */ - delta = -delta; - for (track = tdn->nlt->prev, n = 0; (track) && (n < delta); track = track->prev, n++) { - /* check if space in this track for the strip */ - if (BKE_nlatrack_has_space(track, strip->start, strip->end) && - !BKE_nlatrack_is_nonlocal_in_liboverride(tdn->id, track)) { - /* move strip to this track */ - BKE_nlatrack_remove_strip(tdn->nlt, strip); - BKE_nlatrack_add_strip(track, strip, is_liboverride); + /** We assume all library tracks are grouped at the bottom of the nla stack. Thus, no need + * to check for them when moving tracks upward. */ - tdn->nlt = track; - tdn->trackIndex--; - } - else { /* can't move any further */ - break; - } + while (delta_new_tracks > 0) { + dst_track = dst_track->next; + if (dst_track == NULL) { + break; } + delta_new_tracks--; + } + + /* Auto-grow track list. */ + for (int i = 0; i < -delta_new_tracks; i++) { + NlaTrack *new_track = BKE_nlatrack_new(); + new_track->flag |= NLATRACK_TEMPORARILY_ADDED; + BKE_nlatrack_insert_before( + nla_tracks, (NlaTrack *)nla_tracks->first, new_track, is_liboverride); + dst_track = new_track; + } + + for (int i = 0; i < delta_new_tracks; i++) { + NlaTrack *new_track = BKE_nlatrack_new(); + new_track->flag |= NLATRACK_TEMPORARILY_ADDED; + + BKE_nlatrack_insert_after( + nla_tracks, (NlaTrack *)nla_tracks->last, new_track, is_liboverride); + dst_track = new_track; + } + + /* Move strip from old_track to dst_track. */ + if (dst_track != old_track) { + BKE_nlatrack_remove_strip(old_track, strip); + BKE_nlastrips_add_strip(&dst_track->strips, strip); + + tdn->nlt = dst_track; + tdn->signed_track_index += delta; + tdn->trackIndex = BLI_findindex(nla_tracks, dst_track); + } + + if (tdn->nlt->flag & NLATRACK_PROTECTED) { + strip->flag |= NLASTRIP_FLAG_INVALID_LOCATION; } } @@ -695,6 +813,34 @@ static void nlastrip_shuffle_transformed(TransDataContainer *tc, TransDataNla *f LISTBASE_FOREACH (IDGroupedTransData *, group, &grouped_trans_datas) { ListBase *trans_datas = &group->trans_datas; + /* Apply vertical shuffle. */ + int minimum_track_offset = 0; + const bool track_offset_valid = transdata_get_track_shuffle_offset(trans_datas, + &minimum_track_offset); + + /* Debug assert to ensure strips preserved their relative track offsets from eachother and + * none were compressed. Otherwise, no amount of vertical shuffling is a solution. + * + * This is considered a bug. */ + BLI_assert(track_offset_valid); + if (minimum_track_offset != 0) { + ListBase *tracks = &BKE_animdata_from_id(group->id)->nla_tracks; + + LISTBASE_FOREACH (LinkData *, link, trans_datas) { + TransDataNla *trans_data = (TransDataNla *)link->data; + + trans_data->trackIndex = trans_data->trackIndex + minimum_track_offset; + NlaTrack *dst_track = BLI_findlink(tracks, trans_data->trackIndex); + + NlaStrip *strip = trans_data->strip; + BKE_nlatrack_remove_strip(trans_data->nlt, strip); + // Should this be false? Should we short circuit the loop + BKE_nlatrack_add_strip(dst_track, strip, false); + + trans_data->nlt = dst_track; + } + } + /* Apply horizontal shuffle. */ const float minimum_time_offset = transdata_get_time_shuffle_offset(trans_datas); LISTBASE_FOREACH (LinkData *, link, trans_datas) { @@ -746,6 +892,7 @@ static void special_aftertrans_update__nla(bContext *C, TransInfo *t) } ListBase anim_data = {NULL, NULL}; + bAnimListElem *ale; short filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_FOREDIT | ANIMFILTER_FCURVESONLY); /* get channels to work on */ @@ -770,6 +917,52 @@ static void special_aftertrans_update__nla(bContext *C, TransInfo *t) /* free temp memory */ ANIM_animdata_freelist(&anim_data); + /** Truncate temporarily added tracks. */ + // TODO move this into a method + { + filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_ANIMDATA); + ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, ac.datatype); + + for (ale = anim_data.first; ale; ale = ale->next) { + ListBase *nla_tracks = &ale->adt->nla_tracks; + + /** Remove top tracks that weren't necessary. */ + LISTBASE_FOREACH_BACKWARD_MUTABLE (NlaTrack *, track, nla_tracks) { + if (!(track->flag & NLATRACK_TEMPORARILY_ADDED)) { + break; + } + if (track->strips.first != NULL) { + break; + } + BKE_nlatrack_remove_and_free(nla_tracks, track, true); + } + + /** Remove bottom tracks that weren't necessary. */ + LISTBASE_FOREACH_MUTABLE (NlaTrack *, track, nla_tracks) { + /** Library override tracks are the first N tracks. They're never temporary and determine + * where we start removing temporaries.*/ + if ((track->flag & NLATRACK_OVERRIDELIBRARY_LOCAL) == 0) { + continue; + } + if (!(track->flag & NLATRACK_TEMPORARILY_ADDED)) { + break; + } + if (track->strips.first != NULL) { + break; + } + BKE_nlatrack_remove_and_free(nla_tracks, track, true); + } + + /** Clear temporary flag. */ + LISTBASE_FOREACH_MUTABLE (NlaTrack *, track, nla_tracks) { + track->flag &= ~NLATRACK_TEMPORARILY_ADDED; + } + } + + ANIM_animdata_freelist(&anim_data); + } + // END TODO + /* Perform after-transform validation. */ ED_nla_postop_refresh(&ac); } diff --git a/source/blender/makesdna/DNA_anim_types.h b/source/blender/makesdna/DNA_anim_types.h index 6bb51b35c1b..2c35af5524c 100644 --- a/source/blender/makesdna/DNA_anim_types.h +++ b/source/blender/makesdna/DNA_anim_types.h @@ -901,6 +901,11 @@ typedef enum eNlaTrack_Flag { * usually as result of tweaking being enabled (internal flag) */ NLATRACK_DISABLED = (1 << 10), +// TODO is this the best name? + /** Marks tracks automatically added for space while dragging strips vertically. + * Internal flag that's only set during transform operator. */ + NLATRACK_TEMPORARILY_ADDED = (1 << 11), + /** This NLA track is added to an override ID, which means it is fully editable. * Irrelevant in case the owner ID is not an override. */ NLATRACK_OVERRIDELIBRARY_LOCAL = 1 << 16, -- 2.30.2 From 765d9e76309370b75eb0dd7ff6e838ae63894cff Mon Sep 17 00:00:00 2001 From: Nate Rupsis Date: Thu, 6 Apr 2023 09:17:45 -0400 Subject: [PATCH 3/6] starting some refactroing --- .../editors/transform/transform_convert_nla.c | 96 ++++++++++--------- 1 file changed, 51 insertions(+), 45 deletions(-) diff --git a/source/blender/editors/transform/transform_convert_nla.c b/source/blender/editors/transform/transform_convert_nla.c index 4eeefe313a3..03ac19dbf36 100644 --- a/source/blender/editors/transform/transform_convert_nla.c +++ b/source/blender/editors/transform/transform_convert_nla.c @@ -141,7 +141,7 @@ static float transdata_get_time_shuffle_offset(ListBase *trans_datas) BLI_assert(offset_left <= 0); BLI_assert(offset_right >= 0); - return fabs(offset_left) < offset_right ? offset_left : offset_right; + return -offset_left < offset_right ? offset_left : offset_right; } // TODO go over these comments @@ -231,6 +231,54 @@ static bool transdata_get_track_shuffle_offset(ListBase *trans_datas, int *r_tra return down_valid || up_valid; } +/* -------------------------------------------------------------------- */ +/** \name Transform application to NLA strips + * \{ */ + +/** \} */ +nlatrack_truncate_temporary_tracks() +{ + filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_ANIMDATA); + ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, ac.datatype); + + for (ale = anim_data.first; ale; ale = ale->next) { + ListBase *nla_tracks = &ale->adt->nla_tracks; + + /** Remove top tracks that weren't necessary. */ + LISTBASE_FOREACH_BACKWARD_MUTABLE (NlaTrack *, track, nla_tracks) { + if (!(track->flag & NLATRACK_TEMPORARILY_ADDED)) { + break; + } + if (track->strips.first != NULL) { + break; + } + BKE_nlatrack_remove_and_free(nla_tracks, track, true); + } + + /** Remove bottom tracks that weren't necessary. */ + LISTBASE_FOREACH_MUTABLE (NlaTrack *, track, nla_tracks) { + /** Library override tracks are the first N tracks. They're never temporary and determine + * where we start removing temporaries.*/ + if ((track->flag & NLATRACK_OVERRIDELIBRARY_LOCAL) == 0) { + continue; + } + if (!(track->flag & NLATRACK_TEMPORARILY_ADDED)) { + break; + } + if (track->strips.first != NULL) { + break; + } + BKE_nlatrack_remove_and_free(nla_tracks, track, true); + } + + /** Clear temporary flag. */ + LISTBASE_FOREACH_MUTABLE (NlaTrack *, track, nla_tracks) { + track->flag &= ~NLATRACK_TEMPORARILY_ADDED; + } + } + + ANIM_animdata_freelist(&anim_data); +} /* -------------------------------------------------------------------- */ /** \name Transform application to NLA strips * \{ */ @@ -917,51 +965,9 @@ static void special_aftertrans_update__nla(bContext *C, TransInfo *t) /* free temp memory */ ANIM_animdata_freelist(&anim_data); - /** Truncate temporarily added tracks. */ + /* Truncate temporarily added tracks. */ // TODO move this into a method - { - filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_ANIMDATA); - ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, ac.datatype); - - for (ale = anim_data.first; ale; ale = ale->next) { - ListBase *nla_tracks = &ale->adt->nla_tracks; - - /** Remove top tracks that weren't necessary. */ - LISTBASE_FOREACH_BACKWARD_MUTABLE (NlaTrack *, track, nla_tracks) { - if (!(track->flag & NLATRACK_TEMPORARILY_ADDED)) { - break; - } - if (track->strips.first != NULL) { - break; - } - BKE_nlatrack_remove_and_free(nla_tracks, track, true); - } - - /** Remove bottom tracks that weren't necessary. */ - LISTBASE_FOREACH_MUTABLE (NlaTrack *, track, nla_tracks) { - /** Library override tracks are the first N tracks. They're never temporary and determine - * where we start removing temporaries.*/ - if ((track->flag & NLATRACK_OVERRIDELIBRARY_LOCAL) == 0) { - continue; - } - if (!(track->flag & NLATRACK_TEMPORARILY_ADDED)) { - break; - } - if (track->strips.first != NULL) { - break; - } - BKE_nlatrack_remove_and_free(nla_tracks, track, true); - } - - /** Clear temporary flag. */ - LISTBASE_FOREACH_MUTABLE (NlaTrack *, track, nla_tracks) { - track->flag &= ~NLATRACK_TEMPORARILY_ADDED; - } - } - - ANIM_animdata_freelist(&anim_data); - } - // END TODO + nlatrack_truncate_temporary_tracks(); /* Perform after-transform validation. */ ED_nla_postop_refresh(&ac); -- 2.30.2 From b2e12946a11b7b273fa39c5c6aa3654f0f119293 Mon Sep 17 00:00:00 2001 From: Nate Rupsis Date: Tue, 18 Apr 2023 19:27:05 -0400 Subject: [PATCH 4/6] strip sometimes still disapears... --- .../editors/transform/transform_convert_nla.c | 47 ++++++++++++++----- 1 file changed, 34 insertions(+), 13 deletions(-) diff --git a/source/blender/editors/transform/transform_convert_nla.c b/source/blender/editors/transform/transform_convert_nla.c index 5688cad923e..4120b2024f5 100644 --- a/source/blender/editors/transform/transform_convert_nla.c +++ b/source/blender/editors/transform/transform_convert_nla.c @@ -236,10 +236,12 @@ static bool transdata_get_track_shuffle_offset(ListBase *trans_datas, int *r_tra * \{ */ /** \} */ -nlatrack_truncate_temporary_tracks() +static void nlatrack_truncate_temporary_tracks(bAnimContext *ac) { - filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_ANIMDATA); - ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, ac.datatype); + short filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_ANIMDATA); + ListBase anim_data = {NULL, NULL}; + bAnimListElem *ale; + ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype); for (ale = anim_data.first; ale; ale = ale->next) { ListBase *nla_tracks = &ale->adt->nla_tracks; @@ -779,7 +781,7 @@ static void recalcData_nla(TransInfo *t) /* Move strip from old_track to dst_track. */ if (dst_track != old_track) { BKE_nlatrack_remove_strip(old_track, strip); - BKE_nlastrips_add_strip(&dst_track->strips, strip); + BKE_nlastrips_add_strip_unsafe(&dst_track->strips, strip); tdn->nlt = dst_track; tdn->signed_track_index += delta; @@ -871,16 +873,36 @@ static void nlastrip_shuffle_transformed(TransDataContainer *tc, TransDataNla *f LISTBASE_FOREACH (LinkData *, link, trans_datas) { TransDataNla *trans_data = (TransDataNla *)link->data; + NlaTrack *dst_track = BLI_findlink(tracks, trans_data->trackIndex + minimum_track_offset); - trans_data->trackIndex = trans_data->trackIndex + minimum_track_offset; - NlaTrack *dst_track = BLI_findlink(tracks, trans_data->trackIndex); + // trans_data->trackIndex = trans_data->trackIndex + minimum_track_offset; + // NlaTrack *dst_track = BLI_findlink(tracks, trans_data->trackIndex); - NlaStrip *strip = trans_data->strip; - BKE_nlatrack_remove_strip(trans_data->nlt, strip); - // Should this be false? Should we short circuit the loop - BKE_nlatrack_add_strip(dst_track, strip, false); + if ((dst_track->flag & NLATRACK_PROTECTED) != 0) { - trans_data->nlt = dst_track; + printf("this track isn't protected \n"); + NlaStrip *strip = trans_data->strip; + BKE_nlatrack_remove_strip(trans_data->nlt, strip); + // Should this be false? Should we short circuit the loop + BKE_nlatrack_add_strip(dst_track, strip, false); + + trans_data->nlt = dst_track; + } + else { + printf("this track is protected. Adding in back track \n"); + printf("target track index: %i \n", trans_data->trackIndex); + printf("old track index: %i \n\n", trans_data->oldTrack->index); + + NlaStrip *strip = trans_data->strip; + NlaTrack *old_track = BLI_findlink(tracks, trans_data->oldTrack->index); + + BKE_nlatrack_remove_strip(trans_data->nlt, strip); + // Should this be false? Should we short circuit the loop + // BKE_nlatrack_add_strip(old_track, strip, false); + BKE_nlastrips_add_strip_unsafe(&old_track->strips, strip); + + trans_data->nlt = old_track; + } } } @@ -935,7 +957,6 @@ static void special_aftertrans_update__nla(bContext *C, TransInfo *t) } ListBase anim_data = {NULL, NULL}; - bAnimListElem *ale; short filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_FOREDIT | ANIMFILTER_FCURVESONLY); /* get channels to work on */ @@ -962,7 +983,7 @@ static void special_aftertrans_update__nla(bContext *C, TransInfo *t) /* Truncate temporarily added tracks. */ // TODO move this into a method - nlatrack_truncate_temporary_tracks(); + nlatrack_truncate_temporary_tracks(&ac); /* Perform after-transform validation. */ ED_nla_postop_refresh(&ac); -- 2.30.2 From 135c18e906536ea06ea2c9683719f23b638058b6 Mon Sep 17 00:00:00 2001 From: Nate Rupsis Date: Thu, 20 Apr 2023 01:12:15 -0400 Subject: [PATCH 5/6] need to add unsafe, so it shuffles back --- source/blender/editors/transform/transform_convert_nla.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/source/blender/editors/transform/transform_convert_nla.c b/source/blender/editors/transform/transform_convert_nla.c index 4120b2024f5..71d94bd6b87 100644 --- a/source/blender/editors/transform/transform_convert_nla.c +++ b/source/blender/editors/transform/transform_convert_nla.c @@ -889,10 +889,6 @@ static void nlastrip_shuffle_transformed(TransDataContainer *tc, TransDataNla *f trans_data->nlt = dst_track; } else { - printf("this track is protected. Adding in back track \n"); - printf("target track index: %i \n", trans_data->trackIndex); - printf("old track index: %i \n\n", trans_data->oldTrack->index); - NlaStrip *strip = trans_data->strip; NlaTrack *old_track = BLI_findlink(tracks, trans_data->oldTrack->index); -- 2.30.2 From 0ef5f31d01eb85169f3f089f41d82798b2c4a4f2 Mon Sep 17 00:00:00 2001 From: Nate Rupsis Date: Tue, 2 May 2023 12:24:30 -0400 Subject: [PATCH 6/6] remain active on valid transform. Only auto expand on ctrl+drag --- .../editors/transform/transform_convert_nla.c | 90 ++++++++++++++++--- 1 file changed, 78 insertions(+), 12 deletions(-) diff --git a/source/blender/editors/transform/transform_convert_nla.c b/source/blender/editors/transform/transform_convert_nla.c index 71d94bd6b87..b6f3de4650c 100644 --- a/source/blender/editors/transform/transform_convert_nla.c +++ b/source/blender/editors/transform/transform_convert_nla.c @@ -415,6 +415,58 @@ static void nlastrip_fix_overlapping(TransInfo *t, TransDataNla *tdn, NlaStrip * } } +/** + * TODO make this functional abstration work + */ +static void nlatrack_auto_grow_tracklist(TransInfo *t, + TransDataNla *tdn, + ListBase *nla_tracks, + NlaTrack *dst_track, + int delta_new_tracks, + bool is_liboverride) +{ + + /* Get event to check if ctrl is geld down. */ + wmEvent *event = CTX_wm_window(t->context)->eventstate; + + /* Only grow track list of ctrl key is held down. */ + while (delta_new_tracks < 0) { + dst_track = dst_track->prev; + if ((event->modifier & KM_CTRL) && + (dst_track == NULL || BKE_nlatrack_is_nonlocal_in_liboverride(tdn->id, dst_track))) { + break; + } + delta_new_tracks++; + } + + /** We assume all library tracks are grouped at the bottom of the nla stack. Thus, no need + * to check for them when moving tracks upward. */ + while (delta_new_tracks > 0) { + dst_track = dst_track->next; + if ((event->modifier & KM_CTRL) && dst_track == NULL) { + break; + } + delta_new_tracks--; + } + + /* Check if new tracks need to be added above or below existing tracks.*/ + for (int i = 0; i < -delta_new_tracks; i++) { + NlaTrack *new_track = BKE_nlatrack_new(); + new_track->flag |= NLATRACK_TEMPORARILY_ADDED; + BKE_nlatrack_insert_before( + nla_tracks, (NlaTrack *)nla_tracks->first, new_track, is_liboverride); + dst_track = new_track; + } + + for (int i = 0; i < delta_new_tracks; i++) { + NlaTrack *new_track = BKE_nlatrack_new(); + new_track->flag |= NLATRACK_TEMPORARILY_ADDED; + + BKE_nlatrack_insert_after(nla_tracks, (NlaTrack *)nla_tracks->last, new_track, is_liboverride); + dst_track = new_track; + } +} + /** \} */ /* -------------------------------------------------------------------- */ @@ -739,28 +791,40 @@ static void recalcData_nla(TransInfo *t) */ int delta_new_tracks = delta; + + /* it's possible to drag a strip fast enough to make delta > |1|. We only want to process + * 1 track shift at a time. + */ + CLAMP(delta_new_tracks, -1, 1); dst_track = old_track; + /* Get event to check if ctrl is geld down. */ + wmEvent *event = CTX_wm_window(t->context)->eventstate; + + // nlatrack_auto_grow_tracklist( + // t, tdn, nla_tracks, dst_track, delta_new_tracks, is_liboverride); + + /* Auto-grow track list on ctrl + transform. */ while (delta_new_tracks < 0) { dst_track = dst_track->prev; - if (dst_track == NULL || BKE_nlatrack_is_nonlocal_in_liboverride(tdn->id, dst_track)) { + if ((event->modifier & KM_CTRL) && + (dst_track == NULL || BKE_nlatrack_is_nonlocal_in_liboverride(tdn->id, dst_track))) { break; } delta_new_tracks++; } - /** We assume all library tracks are grouped at the bottom of the nla stack. Thus, no need + /** We assume all library tracks are grouped at the bottom of the nla stack. Thus, no + need * to check for them when moving tracks upward. */ - while (delta_new_tracks > 0) { dst_track = dst_track->next; - if (dst_track == NULL) { + if ((event->modifier & KM_CTRL) && dst_track == NULL) { break; } delta_new_tracks--; } - /* Auto-grow track list. */ for (int i = 0; i < -delta_new_tracks; i++) { NlaTrack *new_track = BKE_nlatrack_new(); new_track->flag |= NLATRACK_TEMPORARILY_ADDED; @@ -778,6 +842,11 @@ static void recalcData_nla(TransInfo *t) dst_track = new_track; } + /* If the destination track is null, then we need to go to the last track. */ + if (dst_track == NULL) { + dst_track = old_track; + } + /* Move strip from old_track to dst_track. */ if (dst_track != old_track) { BKE_nlatrack_remove_strip(old_track, strip); @@ -788,6 +857,9 @@ static void recalcData_nla(TransInfo *t) tdn->trackIndex = BLI_findindex(nla_tracks, dst_track); } + /* Ensure we set the target track as active. */ + BKE_nlatrack_set_active(nla_tracks, dst_track); + if (tdn->nlt->flag & NLATRACK_PROTECTED) { strip->flag |= NLASTRIP_FLAG_INVALID_LOCATION; } @@ -875,13 +947,9 @@ static void nlastrip_shuffle_transformed(TransDataContainer *tc, TransDataNla *f TransDataNla *trans_data = (TransDataNla *)link->data; NlaTrack *dst_track = BLI_findlink(tracks, trans_data->trackIndex + minimum_track_offset); - // trans_data->trackIndex = trans_data->trackIndex + minimum_track_offset; - // NlaTrack *dst_track = BLI_findlink(tracks, trans_data->trackIndex); - + NlaStrip *strip = trans_data->strip; if ((dst_track->flag & NLATRACK_PROTECTED) != 0) { - printf("this track isn't protected \n"); - NlaStrip *strip = trans_data->strip; BKE_nlatrack_remove_strip(trans_data->nlt, strip); // Should this be false? Should we short circuit the loop BKE_nlatrack_add_strip(dst_track, strip, false); @@ -889,7 +957,6 @@ static void nlastrip_shuffle_transformed(TransDataContainer *tc, TransDataNla *f trans_data->nlt = dst_track; } else { - NlaStrip *strip = trans_data->strip; NlaTrack *old_track = BLI_findlink(tracks, trans_data->oldTrack->index); BKE_nlatrack_remove_strip(trans_data->nlt, strip); @@ -978,7 +1045,6 @@ static void special_aftertrans_update__nla(bContext *C, TransInfo *t) ANIM_animdata_freelist(&anim_data); /* Truncate temporarily added tracks. */ - // TODO move this into a method nlatrack_truncate_temporary_tracks(&ac); /* Perform after-transform validation. */ -- 2.30.2