2024-09-21 14:30:48 +02:00
|
|
|
/* SPDX-FileCopyrightText: 2021-2024 Blender Authors
|
2023-05-31 16:19:06 +02:00
|
|
|
*
|
|
|
|
|
* SPDX-License-Identifier: GPL-2.0-or-later */
|
2021-06-16 00:29:17 +02:00
|
|
|
|
|
|
|
|
/** \file
|
|
|
|
|
* \ingroup sequencer
|
|
|
|
|
*/
|
|
|
|
|
|
2023-11-02 01:05:06 +01:00
|
|
|
#include "SEQ_sequencer.hh"
|
|
|
|
|
#include "sequencer.hh"
|
2021-06-16 00:29:17 +02:00
|
|
|
|
|
|
|
|
#include "DNA_listBase.h"
|
|
|
|
|
#include "DNA_scene_types.h"
|
|
|
|
|
#include "DNA_sequence_types.h"
|
|
|
|
|
|
2022-06-02 01:39:40 +02:00
|
|
|
#include "BLI_listbase.h"
|
2023-11-06 01:36:44 +01:00
|
|
|
#include "BLI_map.hh"
|
2021-06-16 00:29:17 +02:00
|
|
|
#include "BLI_sys_types.h"
|
2023-11-06 01:36:44 +01:00
|
|
|
#include "BLI_vector_set.hh"
|
|
|
|
|
|
2023-07-22 11:27:25 +10:00
|
|
|
#include <cstring>
|
2024-09-21 14:30:48 +02:00
|
|
|
#include <mutex>
|
2021-06-16 00:29:17 +02:00
|
|
|
|
|
|
|
|
#include "MEM_guardedalloc.h"
|
|
|
|
|
|
2024-09-21 14:30:48 +02:00
|
|
|
static std::mutex lookup_lock;
|
2021-06-16 00:29:17 +02:00
|
|
|
|
2023-07-20 09:46:24 +02:00
|
|
|
struct SequenceLookup {
|
2024-09-21 14:30:48 +02:00
|
|
|
blender::Map<std::string, Sequence *> seq_by_name;
|
|
|
|
|
blender::Map<const Sequence *, Sequence *> meta_by_seq;
|
2023-11-06 01:36:44 +01:00
|
|
|
blender::Map<const Sequence *, blender::VectorSet<Sequence *>> effects_by_seq;
|
2024-09-21 14:30:48 +02:00
|
|
|
blender::Map<const SeqTimelineChannel *, Sequence *> owner_by_channel;
|
|
|
|
|
bool is_valid = false;
|
2023-07-20 09:46:24 +02:00
|
|
|
};
|
2021-06-16 00:29:17 +02:00
|
|
|
|
2023-11-06 01:36:44 +01:00
|
|
|
static void seq_sequence_lookup_append_effect(const Sequence *input,
|
2022-06-02 01:39:40 +02:00
|
|
|
Sequence *effect,
|
2023-06-03 08:36:28 +10:00
|
|
|
SequenceLookup *lookup)
|
2022-06-02 01:39:40 +02:00
|
|
|
{
|
2023-07-20 09:46:24 +02:00
|
|
|
if (input == nullptr) {
|
2022-06-02 01:39:40 +02:00
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2023-11-06 01:36:44 +01:00
|
|
|
blender::VectorSet<Sequence *> &effects = lookup->effects_by_seq.lookup_or_add_default(input);
|
2022-06-02 01:39:40 +02:00
|
|
|
|
2023-11-06 01:36:44 +01:00
|
|
|
effects.add(effect);
|
2022-06-02 01:39:40 +02:00
|
|
|
}
|
|
|
|
|
|
2023-06-03 08:36:28 +10:00
|
|
|
static void seq_sequence_lookup_build_effect(Sequence *seq, SequenceLookup *lookup)
|
2021-06-16 00:29:17 +02:00
|
|
|
{
|
2022-06-02 01:39:40 +02:00
|
|
|
if ((seq->type & SEQ_TYPE_EFFECT) == 0) {
|
|
|
|
|
return;
|
2021-06-16 00:29:17 +02:00
|
|
|
}
|
2022-06-02 01:39:40 +02:00
|
|
|
|
|
|
|
|
seq_sequence_lookup_append_effect(seq->seq1, seq, lookup);
|
|
|
|
|
seq_sequence_lookup_append_effect(seq->seq2, seq, lookup);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void seq_sequence_lookup_build_from_seqbase(Sequence *parent_meta,
|
|
|
|
|
const ListBase *seqbase,
|
2023-06-03 08:36:28 +10:00
|
|
|
SequenceLookup *lookup)
|
2022-06-02 01:39:40 +02:00
|
|
|
{
|
2024-09-21 14:30:48 +02:00
|
|
|
if (parent_meta != nullptr) {
|
|
|
|
|
LISTBASE_FOREACH (SeqTimelineChannel *, channel, &parent_meta->channels) {
|
|
|
|
|
lookup->owner_by_channel.add(channel, parent_meta);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2022-06-02 01:39:40 +02:00
|
|
|
LISTBASE_FOREACH (Sequence *, seq, seqbase) {
|
2024-09-21 14:30:48 +02:00
|
|
|
lookup->seq_by_name.add(seq->name + 2, seq);
|
|
|
|
|
lookup->meta_by_seq.add(seq, parent_meta);
|
2022-06-02 01:39:40 +02:00
|
|
|
seq_sequence_lookup_build_effect(seq, lookup);
|
|
|
|
|
|
|
|
|
|
if (seq->type == SEQ_TYPE_META) {
|
|
|
|
|
seq_sequence_lookup_build_from_seqbase(seq, &seq->seqbase, lookup);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2023-06-03 08:36:28 +10:00
|
|
|
static void seq_sequence_lookup_build(const Scene *scene, SequenceLookup *lookup)
|
2022-06-02 01:39:40 +02:00
|
|
|
{
|
|
|
|
|
Editing *ed = SEQ_editing_get(scene);
|
2023-07-20 09:46:24 +02:00
|
|
|
seq_sequence_lookup_build_from_seqbase(nullptr, &ed->seqbase, lookup);
|
2024-09-21 14:30:48 +02:00
|
|
|
lookup->is_valid = true;
|
2021-06-16 00:29:17 +02:00
|
|
|
}
|
|
|
|
|
|
2023-07-20 20:11:08 +10:00
|
|
|
static SequenceLookup *seq_sequence_lookup_new()
|
2021-06-16 00:29:17 +02:00
|
|
|
{
|
2023-11-06 01:36:44 +01:00
|
|
|
SequenceLookup *lookup = MEM_new<SequenceLookup>(__func__);
|
2021-06-16 00:29:17 +02:00
|
|
|
return lookup;
|
|
|
|
|
}
|
|
|
|
|
|
2023-06-03 08:36:28 +10:00
|
|
|
static void seq_sequence_lookup_free(SequenceLookup **lookup)
|
2021-06-16 00:29:17 +02:00
|
|
|
{
|
2023-11-06 01:36:44 +01:00
|
|
|
MEM_delete(*lookup);
|
2023-07-20 09:46:24 +02:00
|
|
|
*lookup = nullptr;
|
2021-06-16 00:29:17 +02:00
|
|
|
}
|
|
|
|
|
|
2023-06-03 08:36:28 +10:00
|
|
|
static void seq_sequence_lookup_rebuild(const Scene *scene, SequenceLookup **lookup)
|
2021-06-16 00:29:17 +02:00
|
|
|
{
|
|
|
|
|
seq_sequence_lookup_free(lookup);
|
|
|
|
|
*lookup = seq_sequence_lookup_new();
|
|
|
|
|
seq_sequence_lookup_build(scene, *lookup);
|
|
|
|
|
}
|
|
|
|
|
|
2023-06-03 08:36:28 +10:00
|
|
|
static void seq_sequence_lookup_update_if_needed(const Scene *scene, SequenceLookup **lookup)
|
2021-06-16 00:29:17 +02:00
|
|
|
{
|
|
|
|
|
if (!scene->ed) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
2024-09-21 14:30:48 +02:00
|
|
|
if (*lookup && (*lookup)->is_valid) {
|
2021-06-16 00:29:17 +02:00
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
seq_sequence_lookup_rebuild(scene, lookup);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void SEQ_sequence_lookup_free(const Scene *scene)
|
|
|
|
|
{
|
|
|
|
|
BLI_assert(scene->ed);
|
2024-09-21 14:30:48 +02:00
|
|
|
std::lock_guard lock(lookup_lock);
|
2021-06-16 00:29:17 +02:00
|
|
|
SequenceLookup *lookup = scene->ed->runtime.sequence_lookup;
|
|
|
|
|
seq_sequence_lookup_free(&lookup);
|
|
|
|
|
}
|
|
|
|
|
|
2022-06-02 01:39:40 +02:00
|
|
|
Sequence *SEQ_sequence_lookup_seq_by_name(const Scene *scene, const char *key)
|
|
|
|
|
{
|
|
|
|
|
BLI_assert(scene->ed);
|
2024-09-21 14:30:48 +02:00
|
|
|
std::lock_guard lock(lookup_lock);
|
2022-06-02 01:39:40 +02:00
|
|
|
seq_sequence_lookup_update_if_needed(scene, &scene->ed->runtime.sequence_lookup);
|
|
|
|
|
SequenceLookup *lookup = scene->ed->runtime.sequence_lookup;
|
2024-09-21 14:30:48 +02:00
|
|
|
return lookup->seq_by_name.lookup_default(key, nullptr);
|
2022-06-02 01:39:40 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Sequence *seq_sequence_lookup_meta_by_seq(const Scene *scene, const Sequence *key)
|
2021-06-16 00:29:17 +02:00
|
|
|
{
|
|
|
|
|
BLI_assert(scene->ed);
|
2024-09-21 14:30:48 +02:00
|
|
|
std::lock_guard lock(lookup_lock);
|
2021-06-16 00:29:17 +02:00
|
|
|
seq_sequence_lookup_update_if_needed(scene, &scene->ed->runtime.sequence_lookup);
|
|
|
|
|
SequenceLookup *lookup = scene->ed->runtime.sequence_lookup;
|
2024-09-21 14:30:48 +02:00
|
|
|
return lookup->meta_by_seq.lookup_default(key, nullptr);
|
2021-06-16 00:29:17 +02:00
|
|
|
}
|
|
|
|
|
|
2023-11-06 01:36:44 +01:00
|
|
|
blender::Span<Sequence *> seq_sequence_lookup_effects_by_seq(const Scene *scene,
|
|
|
|
|
const Sequence *key)
|
2022-06-02 01:39:40 +02:00
|
|
|
{
|
|
|
|
|
BLI_assert(scene->ed);
|
2024-09-21 14:30:48 +02:00
|
|
|
std::lock_guard lock(lookup_lock);
|
2022-06-02 01:39:40 +02:00
|
|
|
seq_sequence_lookup_update_if_needed(scene, &scene->ed->runtime.sequence_lookup);
|
|
|
|
|
SequenceLookup *lookup = scene->ed->runtime.sequence_lookup;
|
2023-11-06 01:36:44 +01:00
|
|
|
blender::VectorSet<Sequence *> &effects = lookup->effects_by_seq.lookup_or_add_default(key);
|
|
|
|
|
return effects.as_span();
|
2022-06-02 01:39:40 +02:00
|
|
|
}
|
|
|
|
|
|
2024-09-21 14:30:48 +02:00
|
|
|
Sequence *SEQ_sequence_lookup_owner_by_channel(const Scene *scene,
|
|
|
|
|
const SeqTimelineChannel *channel)
|
2021-06-16 00:29:17 +02:00
|
|
|
{
|
2024-09-21 14:30:48 +02:00
|
|
|
BLI_assert(scene->ed);
|
|
|
|
|
std::lock_guard lock(lookup_lock);
|
|
|
|
|
seq_sequence_lookup_update_if_needed(scene, &scene->ed->runtime.sequence_lookup);
|
|
|
|
|
SequenceLookup *lookup = scene->ed->runtime.sequence_lookup;
|
|
|
|
|
return lookup->owner_by_channel.lookup_default(channel, nullptr);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void SEQ_sequence_lookup_invalidate(const Scene *scene)
|
|
|
|
|
{
|
|
|
|
|
if (scene == nullptr || scene->ed == nullptr) {
|
2021-06-16 00:29:17 +02:00
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2024-09-21 14:30:48 +02:00
|
|
|
std::lock_guard lock(lookup_lock);
|
2021-06-16 00:29:17 +02:00
|
|
|
SequenceLookup *lookup = scene->ed->runtime.sequence_lookup;
|
2023-07-20 09:46:24 +02:00
|
|
|
if (lookup != nullptr) {
|
2024-09-21 14:30:48 +02:00
|
|
|
lookup->is_valid = false;
|
2021-06-16 00:29:17 +02:00
|
|
|
}
|
|
|
|
|
}
|