Cleanup: Minimize seq->tmp usage
Using this persistent field in `select_more_less_seq__internal` was inapropriate in this case. Split select more/less and linked code, because it was mixed in `select_more_less_seq__internal()` These operators work in completely different way. `select_linked_internal()` doesn't use seq->tmp at all. `seq->tmp` was used to mask strips selected by operator while iterating. Use GSet to store temporary data instead of `seq->tmp`. Reviewed By: sergey Differential Revision: https://developer.blender.org/D10326
This commit is contained in:
parent
16abe9343a
commit
66923031e6
Notes:
blender-bot
2023-02-13 18:34:10 +01:00
Referenced by commit adafd7257d
, Fix T88635: VSE: Select Linked gives unpredictable results
Referenced by issue #88635, Video Sequencer: Select Linked gives unpredictable results
|
@ -26,6 +26,7 @@
|
|||
#include <string.h>
|
||||
|
||||
#include "BLI_blenlib.h"
|
||||
#include "BLI_ghash.h"
|
||||
#include "BLI_math.h"
|
||||
#include "BLI_utildefines.h"
|
||||
|
||||
|
@ -771,69 +772,83 @@ void SEQUENCER_OT_select(wmOperatorType *ot)
|
|||
* \{ */
|
||||
|
||||
/* Run recursively to select linked. */
|
||||
static bool select_more_less_seq__internal(Scene *scene, bool sel, const bool linked)
|
||||
static bool select_linked_internal(Scene *scene)
|
||||
{
|
||||
Editing *ed = SEQ_editing_get(scene, false);
|
||||
Sequence *seq, *neighbor;
|
||||
bool changed = false;
|
||||
int isel;
|
||||
|
||||
if (ed == NULL) {
|
||||
return changed;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (sel) {
|
||||
sel = SELECT;
|
||||
isel = 0;
|
||||
}
|
||||
else {
|
||||
sel = 0;
|
||||
isel = SELECT;
|
||||
}
|
||||
bool changed = false;
|
||||
|
||||
if (!linked) {
|
||||
/* If not linked we only want to touch each seq once, newseq. */
|
||||
for (seq = ed->seqbasep->first; seq; seq = seq->next) {
|
||||
seq->tmp = NULL;
|
||||
LISTBASE_FOREACH (Sequence *, seq, SEQ_active_seqbase_get(ed)) {
|
||||
if ((seq->flag & SELECT) != 0) {
|
||||
continue;
|
||||
}
|
||||
/* Only get unselected neighbors. */
|
||||
Sequence *neighbor = find_neighboring_sequence(scene, seq, SEQ_SIDE_LEFT, 0);
|
||||
if (neighbor) {
|
||||
neighbor->flag |= SELECT;
|
||||
recurs_sel_seq(neighbor);
|
||||
changed = true;
|
||||
}
|
||||
neighbor = find_neighboring_sequence(scene, seq, SEQ_SIDE_RIGHT, 0);
|
||||
if (neighbor) {
|
||||
neighbor->flag |= SELECT;
|
||||
recurs_sel_seq(neighbor);
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
|
||||
for (seq = ed->seqbasep->first; seq; seq = seq->next) {
|
||||
if ((seq->flag & SELECT) == sel) {
|
||||
if (linked || (seq->tmp == NULL)) {
|
||||
/* Only get unselected neighbors. */
|
||||
neighbor = find_neighboring_sequence(scene, seq, SEQ_SIDE_LEFT, isel);
|
||||
if (neighbor) {
|
||||
if (sel) {
|
||||
neighbor->flag |= SELECT;
|
||||
recurs_sel_seq(neighbor);
|
||||
}
|
||||
else {
|
||||
neighbor->flag &= ~SELECT;
|
||||
}
|
||||
if (!linked) {
|
||||
neighbor->tmp = (Sequence *)1;
|
||||
}
|
||||
changed = true;
|
||||
}
|
||||
neighbor = find_neighboring_sequence(scene, seq, SEQ_SIDE_RIGHT, isel);
|
||||
if (neighbor) {
|
||||
if (sel) {
|
||||
neighbor->flag |= SELECT;
|
||||
recurs_sel_seq(neighbor);
|
||||
}
|
||||
else {
|
||||
neighbor->flag &= ~SELECT;
|
||||
}
|
||||
if (!linked) {
|
||||
neighbor->tmp = (Sequence *)1;
|
||||
}
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
return changed;
|
||||
}
|
||||
|
||||
/* Select only one linked strip on each side. */
|
||||
static bool select_more_less_seq__internal(Scene *scene, bool select_more)
|
||||
{
|
||||
Editing *ed = SEQ_editing_get(scene, false);
|
||||
|
||||
if (ed == NULL) {
|
||||
return false;
|
||||
}
|
||||
|
||||
GSet *neighbors = BLI_gset_new(BLI_ghashutil_ptrhash, BLI_ghashutil_ptrcmp, "Linked strips");
|
||||
const int neighbor_selection_filter = select_more ? 0 : SELECT;
|
||||
const int selection_filter = select_more ? SELECT : 0;
|
||||
|
||||
LISTBASE_FOREACH (Sequence *, seq, SEQ_active_seqbase_get(ed)) {
|
||||
if ((seq->flag & SELECT) != selection_filter) {
|
||||
continue;
|
||||
}
|
||||
Sequence *neighbor = find_neighboring_sequence(
|
||||
scene, seq, SEQ_SIDE_LEFT, neighbor_selection_filter);
|
||||
if (neighbor) {
|
||||
BLI_gset_add(neighbors, neighbor);
|
||||
}
|
||||
neighbor = find_neighboring_sequence(scene, seq, SEQ_SIDE_RIGHT, neighbor_selection_filter);
|
||||
if (neighbor) {
|
||||
BLI_gset_add(neighbors, neighbor);
|
||||
}
|
||||
}
|
||||
|
||||
bool changed = false;
|
||||
GSetIterator gsi;
|
||||
BLI_gsetIterator_init(&gsi, neighbors);
|
||||
while (!BLI_gsetIterator_done(&gsi)) {
|
||||
Sequence *neighbor = BLI_gsetIterator_getKey(&gsi);
|
||||
if (select_more) {
|
||||
neighbor->flag |= SELECT;
|
||||
recurs_sel_seq(neighbor);
|
||||
}
|
||||
else {
|
||||
neighbor->flag &= ~SELECT;
|
||||
}
|
||||
changed = true;
|
||||
BLI_gsetIterator_step(&gsi);
|
||||
}
|
||||
|
||||
BLI_gset_free(neighbors, NULL);
|
||||
return changed;
|
||||
}
|
||||
|
||||
|
@ -841,7 +856,7 @@ static int sequencer_select_more_exec(bContext *C, wmOperator *UNUSED(op))
|
|||
{
|
||||
Scene *scene = CTX_data_scene(C);
|
||||
|
||||
if (!select_more_less_seq__internal(scene, true, false)) {
|
||||
if (!select_more_less_seq__internal(scene, true)) {
|
||||
return OPERATOR_CANCELLED;
|
||||
}
|
||||
|
||||
|
@ -877,7 +892,7 @@ static int sequencer_select_less_exec(bContext *C, wmOperator *UNUSED(op))
|
|||
{
|
||||
Scene *scene = CTX_data_scene(C);
|
||||
|
||||
if (!select_more_less_seq__internal(scene, false, false)) {
|
||||
if (!select_more_less_seq__internal(scene, false)) {
|
||||
return OPERATOR_CANCELLED;
|
||||
}
|
||||
|
||||
|
@ -934,7 +949,7 @@ static int sequencer_select_linked_pick_invoke(bContext *C, wmOperator *op, cons
|
|||
|
||||
selected = 1;
|
||||
while (selected) {
|
||||
selected = select_more_less_seq__internal(scene, 1, 1);
|
||||
selected = select_linked_internal(scene);
|
||||
}
|
||||
|
||||
ED_outliner_select_sync_from_sequence_tag(C);
|
||||
|
@ -975,7 +990,7 @@ static int sequencer_select_linked_exec(bContext *C, wmOperator *UNUSED(op))
|
|||
|
||||
selected = true;
|
||||
while (selected) {
|
||||
selected = select_more_less_seq__internal(scene, true, true);
|
||||
selected = select_linked_internal(scene);
|
||||
}
|
||||
|
||||
ED_outliner_select_sync_from_sequence_tag(C);
|
||||
|
|
Loading…
Reference in New Issue