forked from bartvdbraak/blender
Politically correct terrible consequencer changes
This patch includes the work done in the terrible consequencer branch that hasn't been merged to master minus a few controversial and WIP stuff, like strip parenting, new sequence data structs and cuddly widgets. What is included: * Strip extensions only when slipping. It can very easily be made an option but with a few strips with overlapping durations it makes view too crowded and difficult to make out. * Threaded waveform loading + code that restores waveforms on undo (not used though, since sound_load recreates everything. There's a patch for review D876) * Toggle to enable backdrop in the strip sequence editor * Toggle to easily turn on/off waveform display * Snapping during transform on sequence boundaries. Snapping to start or end of selection depends on position of mouse when invoking the operator * Snapping of timeline indicator in sequencer to strip boundaries. To use just press and hold ctrl while dragging. Reviewers: campbellbarton Differential Revision: https://developer.blender.org/D904
This commit is contained in:
parent
aa0b268acb
commit
649a2bcc3d
@ -46,6 +46,7 @@
|
||||
#include <cstring>
|
||||
#include <cmath>
|
||||
#include <sstream>
|
||||
#include <iostream>
|
||||
|
||||
#include "AUD_NULLDevice.h"
|
||||
#include "AUD_I3DDevice.h"
|
||||
@ -317,8 +318,9 @@ AUD_SoundInfo AUD_getInfo(AUD_Sound *sound)
|
||||
info.length = reader->getLength() / (float) info.specs.rate;
|
||||
}
|
||||
}
|
||||
catch(AUD_Exception&)
|
||||
catch(AUD_Exception &ae)
|
||||
{
|
||||
std::cout << ae.str << std::endl;
|
||||
}
|
||||
|
||||
return info;
|
||||
@ -1084,7 +1086,7 @@ int AUD_doesPlayback()
|
||||
return -1;
|
||||
}
|
||||
|
||||
int AUD_readSound(AUD_Sound *sound, sample_t *buffer, int length, int samples_per_second)
|
||||
int AUD_readSound(AUD_Sound *sound, sample_t *buffer, int length, int samples_per_second, short *interrupt)
|
||||
{
|
||||
AUD_DeviceSpecs specs;
|
||||
sample_t *buf;
|
||||
@ -1107,6 +1109,9 @@ int AUD_readSound(AUD_Sound *sound, sample_t *buffer, int length, int samples_pe
|
||||
for (int i = 0; i < length; i++) {
|
||||
len = floor(samplejump * (i+1)) - floor(samplejump * i);
|
||||
|
||||
if (*interrupt) {
|
||||
return 0;
|
||||
}
|
||||
aBuffer.assureSize(len * AUD_SAMPLE_SIZE(specs));
|
||||
buf = aBuffer.getBuffer();
|
||||
|
||||
|
@ -646,7 +646,7 @@ extern int AUD_doesPlayback(void);
|
||||
* \param samples_per_second How many samples to read per second of the sound.
|
||||
* \return How many samples really have been read. Always <= length.
|
||||
*/
|
||||
extern int AUD_readSound(AUD_Sound *sound, sample_t *buffer, int length, int samples_per_second);
|
||||
extern int AUD_readSound(AUD_Sound *sound, sample_t *buffer, int length, int samples_per_second, short *interrupt);
|
||||
|
||||
/**
|
||||
* Copies a sound.
|
||||
|
@ -71,6 +71,7 @@ class SEQUENCER_HT_header(Header):
|
||||
row.prop(scene, "lock_frame_selection_to_range", text="", toggle=True)
|
||||
|
||||
layout.prop(st, "view_type", expand=True, text="")
|
||||
layout.prop(st, "waveform_draw_type", text="")
|
||||
|
||||
if st.view_type in {'PREVIEW', 'SEQUENCER_PREVIEW'}:
|
||||
layout.prop(st, "display_mode", expand=True, text="")
|
||||
@ -82,6 +83,7 @@ class SEQUENCER_HT_header(Header):
|
||||
|
||||
layout.separator()
|
||||
layout.operator("sequencer.refresh_all")
|
||||
layout.prop(st, "show_backdrop")
|
||||
else:
|
||||
if st.view_type == 'SEQUENCER_PREVIEW':
|
||||
layout.separator()
|
||||
@ -716,6 +718,7 @@ class SEQUENCER_PT_sound(SequencerButtonsPanel, Panel):
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
st = context.space_data
|
||||
strip = act_strip(context)
|
||||
sound = strip.sound
|
||||
|
||||
@ -734,7 +737,9 @@ class SEQUENCER_PT_sound(SequencerButtonsPanel, Panel):
|
||||
|
||||
row.prop(sound, "use_memory_cache")
|
||||
|
||||
layout.prop(strip, "show_waveform")
|
||||
if st.waveform_draw_type == 'DEFAULT_WAVEFORMS':
|
||||
layout.prop(strip, "show_waveform")
|
||||
|
||||
layout.prop(strip, "volume")
|
||||
layout.prop(strip, "pitch")
|
||||
layout.prop(strip, "pan")
|
||||
|
@ -377,6 +377,17 @@ struct Sequence *BKE_sequence_alloc(ListBase *lb, int cfra, int machine);
|
||||
void BKE_sequence_alpha_mode_from_extension(struct Sequence *seq);
|
||||
void BKE_sequence_init_colorspace(struct Sequence *seq);
|
||||
|
||||
/* RNA enums, just to be more readable */
|
||||
enum {
|
||||
SEQ_SIDE_NONE = 0,
|
||||
SEQ_SIDE_LEFT,
|
||||
SEQ_SIDE_RIGHT,
|
||||
SEQ_SIDE_BOTH
|
||||
};
|
||||
int BKE_sequencer_find_next_prev_edit(
|
||||
struct Scene *scene, int cfra, const short side,
|
||||
const bool do_skip_mute, const bool do_center, const bool do_unselected);
|
||||
|
||||
struct Sequence *BKE_sequencer_add_image_strip(struct bContext *C, ListBase *seqbasep, struct SeqLoadInfo *seq_load);
|
||||
struct Sequence *BKE_sequencer_add_sound_strip(struct bContext *C, ListBase *seqbasep, struct SeqLoadInfo *seq_load);
|
||||
struct Sequence *BKE_sequencer_add_movie_strip(struct bContext *C, ListBase *seqbasep, struct SeqLoadInfo *seq_load);
|
||||
|
@ -71,8 +71,6 @@ void sound_delete(struct Main *bmain, struct bSound *sound);
|
||||
|
||||
void sound_cache(struct bSound *sound);
|
||||
|
||||
void sound_cache_notifying(struct Main *main, struct bSound *sound);
|
||||
|
||||
void sound_delete_cache(struct bSound *sound);
|
||||
|
||||
void sound_load(struct Main *main, struct bSound *sound);
|
||||
@ -132,7 +130,7 @@ int sound_scene_playing(struct Scene *scene);
|
||||
|
||||
void sound_free_waveform(struct bSound *sound);
|
||||
|
||||
void sound_read_waveform(struct bSound *sound);
|
||||
void sound_read_waveform(struct bSound *sound, bool locked, short *stop);
|
||||
|
||||
void sound_update_scene(struct Main *bmain, struct Scene *scene);
|
||||
|
||||
|
@ -892,7 +892,6 @@ void BKE_sequencer_sort(Scene *scene)
|
||||
Editing *ed = BKE_sequencer_editing_get(scene, false);
|
||||
Sequence *seq, *seqt;
|
||||
|
||||
|
||||
if (ed == NULL)
|
||||
return;
|
||||
|
||||
@ -4675,3 +4674,70 @@ bool BKE_sequence_is_valid_check(Sequence *seq)
|
||||
return true;
|
||||
}
|
||||
|
||||
int BKE_sequencer_find_next_prev_edit(
|
||||
Scene *scene, int cfra, const short side,
|
||||
const bool do_skip_mute, const bool do_center, const bool do_unselected)
|
||||
{
|
||||
Editing *ed = BKE_sequencer_editing_get(scene, false);
|
||||
Sequence *seq;
|
||||
|
||||
int dist, best_dist, best_frame = cfra;
|
||||
int seq_frames[2], seq_frames_tot;
|
||||
|
||||
/* in case where both is passed, frame just finds the nearest end while frame_left the nearest start */
|
||||
|
||||
best_dist = MAXFRAME * 2;
|
||||
|
||||
if (ed == NULL) return cfra;
|
||||
|
||||
for (seq = ed->seqbasep->first; seq; seq = seq->next) {
|
||||
int i;
|
||||
|
||||
if (do_skip_mute && (seq->flag & SEQ_MUTE)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (do_unselected && (seq->flag & SELECT))
|
||||
continue;
|
||||
|
||||
if (do_center) {
|
||||
seq_frames[0] = (seq->startdisp + seq->enddisp) / 2;
|
||||
seq_frames_tot = 1;
|
||||
}
|
||||
else {
|
||||
seq_frames[0] = seq->startdisp;
|
||||
seq_frames[1] = seq->enddisp;
|
||||
|
||||
seq_frames_tot = 2;
|
||||
}
|
||||
|
||||
for (i = 0; i < seq_frames_tot; i++) {
|
||||
const int seq_frame = seq_frames[i];
|
||||
|
||||
dist = MAXFRAME * 2;
|
||||
|
||||
switch (side) {
|
||||
case SEQ_SIDE_LEFT:
|
||||
if (seq_frame < cfra) {
|
||||
dist = cfra - seq_frame;
|
||||
}
|
||||
break;
|
||||
case SEQ_SIDE_RIGHT:
|
||||
if (seq_frame > cfra) {
|
||||
dist = seq_frame - cfra;
|
||||
}
|
||||
break;
|
||||
case SEQ_SIDE_BOTH:
|
||||
dist = abs(seq_frame - cfra);
|
||||
break;
|
||||
}
|
||||
|
||||
if (dist < best_dist) {
|
||||
best_frame = seq_frame;
|
||||
best_dist = dist;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return best_frame;
|
||||
}
|
||||
|
@ -36,6 +36,7 @@
|
||||
|
||||
#include "BLI_blenlib.h"
|
||||
#include "BLI_math.h"
|
||||
#include "BLI_threads.h"
|
||||
|
||||
#include "DNA_anim_types.h"
|
||||
#include "DNA_object_types.h"
|
||||
@ -116,6 +117,12 @@ void BKE_sound_free(bSound *sound)
|
||||
}
|
||||
|
||||
sound_free_waveform(sound);
|
||||
|
||||
if (sound->mutex) {
|
||||
BLI_mutex_free(sound->mutex);
|
||||
sound->mutex = NULL;
|
||||
}
|
||||
|
||||
#endif /* WITH_AUDASPACE */
|
||||
}
|
||||
|
||||
@ -296,12 +303,6 @@ void sound_cache(bSound *sound)
|
||||
sound->playback_handle = sound->handle;
|
||||
}
|
||||
|
||||
void sound_cache_notifying(struct Main *main, bSound *sound)
|
||||
{
|
||||
sound_cache(sound);
|
||||
sound_update_sequencer(main, sound);
|
||||
}
|
||||
|
||||
void sound_delete_cache(bSound *sound)
|
||||
{
|
||||
sound->flags &= ~SOUND_FLAGS_CACHING;
|
||||
@ -680,22 +681,40 @@ void sound_free_waveform(bSound *sound)
|
||||
sound->waveform = NULL;
|
||||
}
|
||||
|
||||
void sound_read_waveform(bSound *sound)
|
||||
void sound_read_waveform(bSound *sound, bool locked, short *stop)
|
||||
{
|
||||
AUD_SoundInfo info;
|
||||
|
||||
SoundWaveform *waveform = NULL;
|
||||
|
||||
info = AUD_getInfo(sound->playback_handle);
|
||||
|
||||
|
||||
if (info.length > 0) {
|
||||
SoundWaveform *waveform = MEM_mallocN(sizeof(SoundWaveform), "SoundWaveform");
|
||||
int length = info.length * SOUND_WAVE_SAMPLES_PER_SECOND;
|
||||
|
||||
|
||||
waveform = MEM_mallocN(sizeof(SoundWaveform), "SoundWaveform");
|
||||
waveform->data = MEM_mallocN(length * sizeof(float) * 3, "SoundWaveform.samples");
|
||||
waveform->length = AUD_readSound(sound->playback_handle, waveform->data, length, SOUND_WAVE_SAMPLES_PER_SECOND);
|
||||
|
||||
waveform->length = AUD_readSound(sound->playback_handle, waveform->data, length, SOUND_WAVE_SAMPLES_PER_SECOND, stop);
|
||||
|
||||
if (*stop) {
|
||||
MEM_freeN(waveform->data);
|
||||
MEM_freeN(waveform);
|
||||
if (locked)
|
||||
BLI_mutex_lock(sound->mutex);
|
||||
sound->flags &= ~SOUND_FLAGS_WAVEFORM_LOADING;
|
||||
if (locked)
|
||||
BLI_mutex_unlock(sound->mutex);
|
||||
return;
|
||||
}
|
||||
|
||||
sound_free_waveform(sound);
|
||||
sound->waveform = waveform;
|
||||
}
|
||||
|
||||
if (locked)
|
||||
BLI_mutex_lock(sound->mutex);
|
||||
sound->waveform = waveform;
|
||||
sound->flags &= ~SOUND_FLAGS_WAVEFORM_LOADING;
|
||||
if (locked)
|
||||
BLI_mutex_unlock(sound->mutex);
|
||||
}
|
||||
|
||||
void sound_update_scene(Main *bmain, struct Scene *scene)
|
||||
@ -830,7 +849,7 @@ void sound_stop_scene(struct Scene *UNUSED(scene)) {}
|
||||
void sound_seek_scene(struct Main *UNUSED(bmain), struct Scene *UNUSED(scene)) {}
|
||||
float sound_sync_scene(struct Scene *UNUSED(scene)) { return NAN_FLT; }
|
||||
int sound_scene_playing(struct Scene *UNUSED(scene)) { return -1; }
|
||||
void sound_read_waveform(struct bSound *UNUSED(sound)) {}
|
||||
void sound_read_waveform(struct bSound *sound, bool locked, short *stop) { UNUSED_VARS(sound, locked, stop); }
|
||||
void sound_init_main(struct Main *UNUSED(bmain)) {}
|
||||
void sound_set_cfra(int UNUSED(cfra)) {}
|
||||
void sound_update_sequencer(struct Main *UNUSED(main), struct bSound *UNUSED(sound)) {}
|
||||
|
@ -308,6 +308,9 @@ BlendFileData *BLO_read_from_memfile(Main *oldmain, const char *filename, MemFil
|
||||
|
||||
/* makes lookup of existing video clips in old main */
|
||||
blo_make_movieclip_pointer_map(fd, oldmain);
|
||||
|
||||
/* make lookups of existing sound data in old main */
|
||||
blo_make_sound_pointer_map(fd, oldmain);
|
||||
|
||||
/* removed packed data from this trick - it's internal data that needs saves */
|
||||
|
||||
@ -318,7 +321,10 @@ BlendFileData *BLO_read_from_memfile(Main *oldmain, const char *filename, MemFil
|
||||
|
||||
/* ensures relinked movie clips are not freed */
|
||||
blo_end_movieclip_pointer_map(fd, oldmain);
|
||||
|
||||
|
||||
/* ensures relinked sounds are not freed */
|
||||
blo_end_sound_pointer_map(fd, oldmain);
|
||||
|
||||
/* move libraries from old main to new main */
|
||||
if (bfd && mainlist.first != mainlist.last) {
|
||||
|
||||
|
@ -1128,6 +1128,8 @@ void blo_freefiledata(FileData *fd)
|
||||
oldnewmap_free(fd->imamap);
|
||||
if (fd->movieclipmap)
|
||||
oldnewmap_free(fd->movieclipmap);
|
||||
if (fd->soundmap)
|
||||
oldnewmap_free(fd->soundmap);
|
||||
if (fd->packedmap)
|
||||
oldnewmap_free(fd->packedmap);
|
||||
if (fd->libmap && !(fd->flags & FD_FLAGS_NOT_MY_LIBMAP))
|
||||
@ -1221,6 +1223,13 @@ static void *newmclipadr(FileData *fd, void *adr) /* used to restore movie
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void *newsoundadr(FileData *fd, void *adr) /* used to restore sound data after undo */
|
||||
{
|
||||
if (fd->soundmap && adr)
|
||||
return oldnewmap_lookup_and_inc(fd->soundmap, adr, true);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void *newpackedadr(FileData *fd, void *adr) /* used to restore packed data after undo */
|
||||
{
|
||||
if (fd->packedmap && adr)
|
||||
@ -1437,6 +1446,37 @@ void blo_end_movieclip_pointer_map(FileData *fd, Main *oldmain)
|
||||
}
|
||||
}
|
||||
|
||||
void blo_make_sound_pointer_map(FileData *fd, Main *oldmain)
|
||||
{
|
||||
bSound *sound = oldmain->sound.first;
|
||||
|
||||
fd->soundmap = oldnewmap_new();
|
||||
|
||||
for (; sound; sound = sound->id.next) {
|
||||
if (sound->waveform)
|
||||
oldnewmap_insert(fd->soundmap, sound->waveform, sound->waveform, 0);
|
||||
}
|
||||
}
|
||||
|
||||
/* set old main sound caches to zero if it has been restored */
|
||||
/* this works because freeing old main only happens after this call */
|
||||
void blo_end_sound_pointer_map(FileData *fd, Main *oldmain)
|
||||
{
|
||||
OldNew *entry = fd->soundmap->entries;
|
||||
bSound *sound = oldmain->sound.first;
|
||||
int i;
|
||||
|
||||
/* used entries were restored, so we put them to zero */
|
||||
for (i = 0; i < fd->soundmap->nentries; i++, entry++) {
|
||||
if (entry->nr > 0)
|
||||
entry->newp = NULL;
|
||||
}
|
||||
|
||||
for (; sound; sound = sound->id.next) {
|
||||
sound->waveform = newsoundadr(fd, sound->waveform);
|
||||
}
|
||||
}
|
||||
|
||||
/* XXX disabled this feature - packed files also belong in temp saves and quit.blend, to make restore work */
|
||||
|
||||
static void insert_packedmap(FileData *fd, PackedFile *pf)
|
||||
@ -5457,7 +5497,7 @@ static void direct_link_scene(FileData *fd, Scene *sce)
|
||||
}
|
||||
|
||||
if (sce->ed) {
|
||||
ListBase *old_seqbasep = &((Editing *)sce->ed)->seqbase;
|
||||
ListBase *old_seqbasep = &sce->ed->seqbase;
|
||||
|
||||
ed = sce->ed = newdataadr(fd, sce->ed);
|
||||
|
||||
@ -5471,6 +5511,7 @@ static void direct_link_scene(FileData *fd, Scene *sce)
|
||||
seq->seq1= newdataadr(fd, seq->seq1);
|
||||
seq->seq2= newdataadr(fd, seq->seq2);
|
||||
seq->seq3= newdataadr(fd, seq->seq3);
|
||||
|
||||
/* a patch: after introduction of effects with 3 input strips */
|
||||
if (seq->seq3 == NULL) seq->seq3 = seq->seq2;
|
||||
|
||||
@ -6776,14 +6817,26 @@ static void direct_link_sound(FileData *fd, bSound *sound)
|
||||
{
|
||||
sound->handle = NULL;
|
||||
sound->playback_handle = NULL;
|
||||
sound->waveform = NULL;
|
||||
|
||||
// versioning stuff, if there was a cache, then we enable caching:
|
||||
/* versioning stuff, if there was a cache, then we enable caching: */
|
||||
if (sound->cache) {
|
||||
sound->flags |= SOUND_FLAGS_CACHING;
|
||||
sound->cache = NULL;
|
||||
}
|
||||
|
||||
if (fd->soundmap) {
|
||||
sound->waveform = newsoundadr(fd, sound->waveform);
|
||||
}
|
||||
else {
|
||||
sound->waveform = NULL;
|
||||
}
|
||||
|
||||
if (sound->mutex)
|
||||
sound->mutex = BLI_mutex_alloc();
|
||||
|
||||
/* clear waveform loading flag */
|
||||
sound->flags &= ~SOUND_FLAGS_WAVEFORM_LOADING;
|
||||
|
||||
sound->packedfile = direct_link_packedfile(fd, sound->packedfile);
|
||||
sound->newpackedfile = direct_link_packedfile(fd, sound->newpackedfile);
|
||||
}
|
||||
|
@ -88,6 +88,7 @@ typedef struct FileData {
|
||||
struct OldNewMap *libmap;
|
||||
struct OldNewMap *imamap;
|
||||
struct OldNewMap *movieclipmap;
|
||||
struct OldNewMap *soundmap;
|
||||
struct OldNewMap *packedmap;
|
||||
|
||||
struct BHeadSort *bheadmap;
|
||||
@ -133,6 +134,8 @@ void blo_make_image_pointer_map(FileData *fd, Main *oldmain);
|
||||
void blo_end_image_pointer_map(FileData *fd, Main *oldmain);
|
||||
void blo_make_movieclip_pointer_map(FileData *fd, Main *oldmain);
|
||||
void blo_end_movieclip_pointer_map(FileData *fd, Main *oldmain);
|
||||
void blo_make_sound_pointer_map(FileData *fd, Main *oldmain);
|
||||
void blo_end_sound_pointer_map(FileData *fd, Main *oldmain);
|
||||
void blo_make_packed_pointer_map(FileData *fd, Main *oldmain);
|
||||
void blo_end_packed_pointer_map(FileData *fd, Main *oldmain);
|
||||
void blo_add_library_pointer_map(ListBase *mainlist, FileData *fd);
|
||||
|
@ -156,6 +156,7 @@
|
||||
#include "BKE_node.h"
|
||||
#include "BKE_report.h"
|
||||
#include "BKE_sequencer.h"
|
||||
#include "BKE_sound.h"
|
||||
#include "BKE_subsurf.h"
|
||||
#include "BKE_modifier.h"
|
||||
#include "BKE_fcurve.h"
|
||||
|
@ -41,6 +41,7 @@
|
||||
#include "DNA_scene_types.h"
|
||||
|
||||
#include "BKE_context.h"
|
||||
#include "BKE_sequencer.h"
|
||||
#include "BKE_global.h"
|
||||
#include "BKE_main.h"
|
||||
#include "BKE_sound.h"
|
||||
@ -92,9 +93,15 @@ static void change_frame_apply(bContext *C, wmOperator *op)
|
||||
{
|
||||
Main *bmain = CTX_data_main(C);
|
||||
Scene *scene = CTX_data_scene(C);
|
||||
|
||||
int frame = RNA_int_get(op->ptr, "frame");
|
||||
bool do_snap = RNA_boolean_get(op->ptr, "snap");
|
||||
|
||||
if (do_snap && CTX_wm_space_seq(C)) {
|
||||
frame = BKE_sequencer_find_next_prev_edit(scene, frame, SEQ_SIDE_BOTH, true, false, false);
|
||||
}
|
||||
|
||||
/* set the new frame number */
|
||||
CFRA = RNA_int_get(op->ptr, "frame");
|
||||
CFRA = frame;
|
||||
FRAMENUMBER_MIN_CLAMP(CFRA);
|
||||
SUBFRA = 0.0f;
|
||||
|
||||
@ -144,7 +151,7 @@ static int change_frame_invoke(bContext *C, wmOperator *op, const wmEvent *event
|
||||
* click-dragging over a range (modal scrubbing).
|
||||
*/
|
||||
RNA_int_set(op->ptr, "frame", frame_from_event(C, event));
|
||||
|
||||
|
||||
change_frame_apply(C, op);
|
||||
|
||||
/* add temp handler */
|
||||
@ -175,6 +182,16 @@ static int change_frame_modal(bContext *C, wmOperator *op, const wmEvent *event)
|
||||
if (event->val == KM_RELEASE)
|
||||
return OPERATOR_FINISHED;
|
||||
break;
|
||||
|
||||
case LEFTCTRLKEY:
|
||||
case RIGHTCTRLKEY:
|
||||
if (event->val == KM_RELEASE) {
|
||||
RNA_boolean_set(op->ptr, "snap", false);
|
||||
}
|
||||
else if (event->val == KM_PRESS) {
|
||||
RNA_boolean_set(op->ptr, "snap", true);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return OPERATOR_RUNNING_MODAL;
|
||||
@ -182,6 +199,8 @@ static int change_frame_modal(bContext *C, wmOperator *op, const wmEvent *event)
|
||||
|
||||
static void ANIM_OT_change_frame(wmOperatorType *ot)
|
||||
{
|
||||
PropertyRNA *prop;
|
||||
|
||||
/* identifiers */
|
||||
ot->name = "Change Frame";
|
||||
ot->idname = "ANIM_OT_change_frame";
|
||||
@ -198,6 +217,8 @@ static void ANIM_OT_change_frame(wmOperatorType *ot)
|
||||
|
||||
/* rna */
|
||||
ot->prop = RNA_def_int(ot->srna, "frame", 0, MINAFRAME, MAXFRAME, "Frame", "", MINAFRAME, MAXFRAME);
|
||||
prop = RNA_def_boolean(ot->srna, "snap", false, "Snap", "");
|
||||
RNA_def_property_flag(prop, PROP_SKIP_SAVE);
|
||||
}
|
||||
|
||||
/* ****************** set preview range operator ****************************/
|
||||
|
@ -43,6 +43,7 @@ set(SRC
|
||||
sequencer_edit.c
|
||||
sequencer_modifier.c
|
||||
sequencer_ops.c
|
||||
sequencer_preview.c
|
||||
sequencer_scopes.c
|
||||
sequencer_select.c
|
||||
sequencer_view.c
|
||||
|
@ -34,6 +34,7 @@
|
||||
#include "BLI_blenlib.h"
|
||||
#include "BLI_math.h"
|
||||
#include "BLI_utildefines.h"
|
||||
#include "BLI_threads.h"
|
||||
|
||||
#include "IMB_imbuf_types.h"
|
||||
|
||||
@ -62,6 +63,7 @@
|
||||
#include "ED_mask.h"
|
||||
#include "ED_sequencer.h"
|
||||
#include "ED_space_api.h"
|
||||
#include "ED_screen.h"
|
||||
|
||||
#include "UI_interface.h"
|
||||
#include "UI_resources.h"
|
||||
@ -69,6 +71,8 @@
|
||||
|
||||
#include "WM_api.h"
|
||||
|
||||
#include "MEM_guardedalloc.h"
|
||||
|
||||
/* own include */
|
||||
#include "sequencer_intern.h"
|
||||
|
||||
@ -86,9 +90,7 @@
|
||||
#undef SEQP_BEGIN
|
||||
#undef SEQ_END
|
||||
|
||||
static void draw_shadedstrip(Sequence *seq, unsigned char col[3], float x1, float y1, float x2, float y2);
|
||||
|
||||
static void get_seq_color3ubv(Scene *curscene, Sequence *seq, unsigned char col[3])
|
||||
void color3ubv_from_seq(Scene *curscene, Sequence *seq, unsigned char col[3])
|
||||
{
|
||||
unsigned char blendcol[3];
|
||||
SolidColorVars *colvars = (SolidColorVars *)seq->effectdata;
|
||||
@ -179,14 +181,14 @@ static void get_seq_color3ubv(Scene *curscene, Sequence *seq, unsigned char col[
|
||||
}
|
||||
}
|
||||
|
||||
static void drawseqwave(Scene *scene, Sequence *seq, float x1, float y1, float x2, float y2, float stepsize)
|
||||
static void drawseqwave(const bContext *C, SpaceSeq *sseq, Scene *scene, Sequence *seq, float x1, float y1, float x2, float y2, float stepsize)
|
||||
{
|
||||
/*
|
||||
* x1 is the starting x value to draw the wave,
|
||||
* x2 the end x value, same for y1 and y2
|
||||
* stepsize is width of a pixel.
|
||||
*/
|
||||
if (seq->flag & SEQ_AUDIO_DRAW_WAVEFORM) {
|
||||
if ((sseq->flag & SEQ_ALL_WAVEFORMS) || (seq->flag & SEQ_AUDIO_DRAW_WAVEFORM)) {
|
||||
int i, j, pos;
|
||||
int length = floor((x2 - x1) / stepsize) + 1;
|
||||
float ymid = (y1 + y2) / 2;
|
||||
@ -194,20 +196,30 @@ static void drawseqwave(Scene *scene, Sequence *seq, float x1, float y1, float x
|
||||
float samplestep;
|
||||
float startsample, endsample;
|
||||
float value;
|
||||
|
||||
bSound *sound = seq->sound;
|
||||
|
||||
SoundWaveform *waveform;
|
||||
|
||||
if (!seq->sound->waveform)
|
||||
sound_read_waveform(seq->sound);
|
||||
|
||||
if (!seq->sound->waveform)
|
||||
return; /* zero length sound */
|
||||
|
||||
|
||||
if (!sound->mutex)
|
||||
sound->mutex = BLI_mutex_alloc();
|
||||
|
||||
BLI_mutex_lock(sound->mutex);
|
||||
if (!seq->sound->waveform) {
|
||||
if(!(sound->flags & SOUND_FLAGS_WAVEFORM_LOADING)) {
|
||||
/* prevent sounds from reloading */
|
||||
seq->sound->flags |= SOUND_FLAGS_WAVEFORM_LOADING;
|
||||
BLI_mutex_unlock(sound->mutex);
|
||||
sequencer_preview_add_sound(C, seq);
|
||||
}
|
||||
else {
|
||||
BLI_mutex_unlock(sound->mutex);
|
||||
}
|
||||
return; /* nothing to draw */
|
||||
}
|
||||
BLI_mutex_unlock(sound->mutex);
|
||||
|
||||
waveform = seq->sound->waveform;
|
||||
|
||||
if (!waveform)
|
||||
return;
|
||||
|
||||
|
||||
startsample = floor((seq->startofs + seq->anim_startofs) / FPS * SOUND_WAVE_SAMPLES_PER_SECOND);
|
||||
endsample = ceil((seq->startofs + seq->anim_startofs + seq->enddisp - seq->startdisp) / FPS * SOUND_WAVE_SAMPLES_PER_SECOND);
|
||||
samplestep = (endsample - startsample) * stepsize / (x2 - x1);
|
||||
@ -303,7 +315,7 @@ static void drawmeta_contents(Scene *scene, Sequence *seqm, float x1, float y1,
|
||||
if ((seqm->flag & SEQ_MUTE) == 0 && (seq->flag & SEQ_MUTE))
|
||||
drawmeta_stipple(1);
|
||||
|
||||
get_seq_color3ubv(scene, seq, col);
|
||||
color3ubv_from_seq(scene, seq, col);
|
||||
|
||||
glColor4ubv(col);
|
||||
|
||||
@ -422,112 +434,6 @@ static void draw_seq_handle(View2D *v2d, Sequence *seq, const float handsize_cla
|
||||
}
|
||||
}
|
||||
|
||||
static void draw_seq_extensions(Scene *scene, ARegion *ar, Sequence *seq)
|
||||
{
|
||||
float x1, x2, y1, y2, pixely, a;
|
||||
unsigned char col[3], blendcol[3];
|
||||
View2D *v2d = &ar->v2d;
|
||||
|
||||
if (seq->type >= SEQ_TYPE_EFFECT) return;
|
||||
|
||||
x1 = seq->startdisp;
|
||||
x2 = seq->enddisp;
|
||||
|
||||
y1 = seq->machine + SEQ_STRIP_OFSBOTTOM;
|
||||
y2 = seq->machine + SEQ_STRIP_OFSTOP;
|
||||
|
||||
pixely = BLI_rctf_size_y(&v2d->cur) / BLI_rcti_size_y(&v2d->mask);
|
||||
|
||||
if (pixely <= 0) return; /* can happen when the view is split/resized */
|
||||
|
||||
blendcol[0] = blendcol[1] = blendcol[2] = 120;
|
||||
|
||||
if (seq->startofs) {
|
||||
glEnable(GL_BLEND);
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
|
||||
get_seq_color3ubv(scene, seq, col);
|
||||
|
||||
if (seq->flag & SELECT) {
|
||||
UI_GetColorPtrBlendShade3ubv(col, blendcol, col, 0.3, -40);
|
||||
glColor4ub(col[0], col[1], col[2], 170);
|
||||
}
|
||||
else {
|
||||
UI_GetColorPtrBlendShade3ubv(col, blendcol, col, 0.6, 0);
|
||||
glColor4ub(col[0], col[1], col[2], 110);
|
||||
}
|
||||
|
||||
glRectf((float)(seq->start), y1 - SEQ_STRIP_OFSBOTTOM, x1, y1);
|
||||
|
||||
if (seq->flag & SELECT) glColor4ub(col[0], col[1], col[2], 255);
|
||||
else glColor4ub(col[0], col[1], col[2], 160);
|
||||
|
||||
fdrawbox((float)(seq->start), y1 - SEQ_STRIP_OFSBOTTOM, x1, y1); //outline
|
||||
|
||||
glDisable(GL_BLEND);
|
||||
}
|
||||
if (seq->endofs) {
|
||||
glEnable(GL_BLEND);
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
|
||||
get_seq_color3ubv(scene, seq, col);
|
||||
|
||||
if (seq->flag & SELECT) {
|
||||
UI_GetColorPtrBlendShade3ubv(col, blendcol, col, 0.3, -40);
|
||||
glColor4ub(col[0], col[1], col[2], 170);
|
||||
}
|
||||
else {
|
||||
UI_GetColorPtrBlendShade3ubv(col, blendcol, col, 0.6, 0);
|
||||
glColor4ub(col[0], col[1], col[2], 110);
|
||||
}
|
||||
|
||||
glRectf(x2, y2, (float)(seq->start + seq->len), y2 + SEQ_STRIP_OFSBOTTOM);
|
||||
|
||||
if (seq->flag & SELECT) glColor4ub(col[0], col[1], col[2], 255);
|
||||
else glColor4ub(col[0], col[1], col[2], 160);
|
||||
|
||||
fdrawbox(x2, y2, (float)(seq->start + seq->len), y2 + SEQ_STRIP_OFSBOTTOM); //outline
|
||||
|
||||
glDisable(GL_BLEND);
|
||||
}
|
||||
if (seq->startstill) {
|
||||
get_seq_color3ubv(scene, seq, col);
|
||||
UI_GetColorPtrBlendShade3ubv(col, blendcol, col, 0.75, 40);
|
||||
glColor3ubv((GLubyte *)col);
|
||||
|
||||
draw_shadedstrip(seq, col, x1, y1, (float)(seq->start), y2);
|
||||
|
||||
/* feint pinstripes, helps see exactly which is extended and which isn't,
|
||||
* especially when the extension is very small */
|
||||
if (seq->flag & SELECT) UI_GetColorPtrBlendShade3ubv(col, col, col, 0.0, 24);
|
||||
else UI_GetColorPtrShade3ubv(col, col, -16);
|
||||
|
||||
glColor3ubv((GLubyte *)col);
|
||||
|
||||
for (a = y1; a < y2; a += pixely * 2.0f) {
|
||||
fdrawline(x1, a, (float)(seq->start), a);
|
||||
}
|
||||
}
|
||||
if (seq->endstill) {
|
||||
get_seq_color3ubv(scene, seq, col);
|
||||
UI_GetColorPtrBlendShade3ubv(col, blendcol, col, 0.75, 40);
|
||||
glColor3ubv((GLubyte *)col);
|
||||
|
||||
draw_shadedstrip(seq, col, (float)(seq->start + seq->len), y1, x2, y2);
|
||||
|
||||
/* feint pinstripes, helps see exactly which is extended and which isn't,
|
||||
* especially when the extension is very small */
|
||||
if (seq->flag & SELECT) UI_GetColorPtrShade3ubv(col, col, 24);
|
||||
else UI_GetColorPtrShade3ubv(col, col, -16);
|
||||
|
||||
glColor3ubv((GLubyte *)col);
|
||||
|
||||
for (a = y1; a < y2; a += pixely * 2.0f) {
|
||||
fdrawline((float)(seq->start + seq->len), a, x2, a);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* draw info text on a sequence strip */
|
||||
static void draw_seq_text(View2D *v2d, Sequence *seq, float x1, float x2, float y1, float y2, const unsigned char background_col[3])
|
||||
{
|
||||
@ -634,7 +540,7 @@ static void draw_seq_text(View2D *v2d, Sequence *seq, float x1, float x2, float
|
||||
}
|
||||
|
||||
/* draws a shaded strip, made from gradient + flat color + gradient */
|
||||
static void draw_shadedstrip(Sequence *seq, unsigned char col[3], float x1, float y1, float x2, float y2)
|
||||
void draw_shadedstrip(Sequence *seq, unsigned char col[3], float x1, float y1, float x2, float y2)
|
||||
{
|
||||
float ymid1, ymid2;
|
||||
|
||||
@ -696,7 +602,7 @@ static void draw_shadedstrip(Sequence *seq, unsigned char col[3], float x1, floa
|
||||
* ARegion is currently only used to get the windows width in pixels
|
||||
* so wave file sample drawing precision is zoom adjusted
|
||||
*/
|
||||
static void draw_seq_strip(Scene *scene, ARegion *ar, Sequence *seq, int outline_tint, float pixelx)
|
||||
static void draw_seq_strip(const bContext *C, SpaceSeq *sseq, Scene *scene, ARegion *ar, Sequence *seq, int outline_tint, float pixelx)
|
||||
{
|
||||
View2D *v2d = &ar->v2d;
|
||||
float x1, x2, y1, y2;
|
||||
@ -714,8 +620,8 @@ static void draw_seq_strip(Scene *scene, ARegion *ar, Sequence *seq, int outline
|
||||
|
||||
|
||||
/* get the correct color per strip type*/
|
||||
//get_seq_color3ubv(scene, seq, col);
|
||||
get_seq_color3ubv(scene, seq, background_col);
|
||||
//color3ubv_from_seq(scene, seq, col);
|
||||
color3ubv_from_seq(scene, seq, background_col);
|
||||
|
||||
/* draw the main strip body */
|
||||
if (is_single_image) { /* single image */
|
||||
@ -727,10 +633,6 @@ static void draw_seq_strip(Scene *scene, ARegion *ar, Sequence *seq, int outline
|
||||
draw_shadedstrip(seq, background_col, x1, y1, x2, y2);
|
||||
}
|
||||
|
||||
/* draw additional info and controls */
|
||||
if (!is_single_image)
|
||||
draw_seq_extensions(scene, ar, seq);
|
||||
|
||||
draw_seq_handle(v2d, seq, handsize_clamped, SEQ_LEFTHANDLE);
|
||||
draw_seq_handle(v2d, seq, handsize_clamped, SEQ_RIGHTHANDLE);
|
||||
|
||||
@ -740,7 +642,9 @@ static void draw_seq_strip(Scene *scene, ARegion *ar, Sequence *seq, int outline
|
||||
|
||||
/* draw sound wave */
|
||||
if (seq->type == SEQ_TYPE_SOUND_RAM) {
|
||||
drawseqwave(scene, seq, x1, y1, x2, y2, BLI_rctf_size_x(&ar->v2d.cur) / ar->winx);
|
||||
if(!(sseq->flag & SEQ_NO_WAVEFORMS)) {
|
||||
drawseqwave(C, sseq, scene, seq, x1, y1, x2, y2, BLI_rctf_size_x(&ar->v2d.cur) / ar->winx);
|
||||
}
|
||||
}
|
||||
|
||||
/* draw lock */
|
||||
@ -773,7 +677,7 @@ static void draw_seq_strip(Scene *scene, ARegion *ar, Sequence *seq, int outline
|
||||
glDisable(GL_POLYGON_STIPPLE);
|
||||
}
|
||||
|
||||
get_seq_color3ubv(scene, seq, col);
|
||||
color3ubv_from_seq(scene, seq, col);
|
||||
if ((G.moving & G_TRANSFORM_SEQ) && (seq->flag & SELECT)) {
|
||||
if (seq->flag & SEQ_OVERLAP) {
|
||||
col[0] = 255; col[1] = col[2] = 40;
|
||||
@ -924,7 +828,7 @@ static ImBuf *sequencer_make_scope(Scene *scene, ImBuf *ibuf, ImBuf *(*make_scop
|
||||
return scope;
|
||||
}
|
||||
|
||||
void draw_image_seq(const bContext *C, Scene *scene, ARegion *ar, SpaceSeq *sseq, int cfra, int frame_ofs, bool draw_overlay)
|
||||
void draw_image_seq(const bContext *C, Scene *scene, ARegion *ar, SpaceSeq *sseq, int cfra, int frame_ofs, bool draw_overlay, bool draw_backdrop)
|
||||
{
|
||||
struct Main *bmain = CTX_data_main(C);
|
||||
struct ImBuf *ibuf = NULL;
|
||||
@ -980,7 +884,7 @@ void draw_image_seq(const bContext *C, Scene *scene, ARegion *ar, SpaceSeq *sseq
|
||||
viewrecty /= proxy_size / 100.0f;
|
||||
}
|
||||
|
||||
if (!draw_overlay || sseq->overlay_type == SEQ_DRAW_OVERLAY_REFERENCE) {
|
||||
if ((!draw_overlay || sseq->overlay_type == SEQ_DRAW_OVERLAY_REFERENCE) && !draw_backdrop) {
|
||||
UI_GetThemeColor3fv(TH_SEQ_PREVIEW, col);
|
||||
glClearColor(col[0], col[1], col[2], 0.0);
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
@ -1055,23 +959,25 @@ void draw_image_seq(const bContext *C, Scene *scene, ARegion *ar, SpaceSeq *sseq
|
||||
/* without this colors can flicker from previous opengl state */
|
||||
glColor4ub(255, 255, 255, 255);
|
||||
|
||||
UI_view2d_totRect_set(v2d, viewrectx + 0.5f, viewrecty + 0.5f);
|
||||
UI_view2d_curRect_validate(v2d);
|
||||
|
||||
/* setting up the view - actual drawing starts here */
|
||||
UI_view2d_view_ortho(v2d);
|
||||
|
||||
/* only draw alpha for main buffer */
|
||||
if (sseq->mainb == SEQ_DRAW_IMG_IMBUF) {
|
||||
if (sseq->flag & SEQ_USE_ALPHA) {
|
||||
glEnable(GL_BLEND);
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
|
||||
fdrawcheckerboard(v2d->tot.xmin, v2d->tot.ymin, v2d->tot.xmax, v2d->tot.ymax);
|
||||
glColor4f(1.0, 1.0, 1.0, 1.0);
|
||||
if (!draw_backdrop) {
|
||||
UI_view2d_totRect_set(v2d, viewrectx + 0.5f, viewrecty + 0.5f);
|
||||
UI_view2d_curRect_validate(v2d);
|
||||
|
||||
/* setting up the view - actual drawing starts here */
|
||||
UI_view2d_view_ortho(v2d);
|
||||
|
||||
/* only draw alpha for main buffer */
|
||||
if (sseq->mainb == SEQ_DRAW_IMG_IMBUF) {
|
||||
if (sseq->flag & SEQ_USE_ALPHA) {
|
||||
glEnable(GL_BLEND);
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
|
||||
fdrawcheckerboard(v2d->tot.xmin, v2d->tot.ymin, v2d->tot.xmax, v2d->tot.ymax);
|
||||
glColor4f(1.0, 1.0, 1.0, 1.0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (scope) {
|
||||
IMB_freeImBuf(ibuf);
|
||||
ibuf = scope;
|
||||
@ -1161,6 +1067,14 @@ void draw_image_seq(const bContext *C, Scene *scene, ARegion *ar, SpaceSeq *sseq
|
||||
else
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, ibuf->x, ibuf->y, 0, format, type, display_buffer);
|
||||
|
||||
if (draw_backdrop) {
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glPushMatrix();
|
||||
glLoadIdentity();
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glPushMatrix();
|
||||
glLoadIdentity();
|
||||
}
|
||||
glBegin(GL_QUADS);
|
||||
|
||||
if (draw_overlay) {
|
||||
@ -1183,6 +1097,25 @@ void draw_image_seq(const bContext *C, Scene *scene, ARegion *ar, SpaceSeq *sseq
|
||||
glTexCoord2f(1.0f, 0.0f); glVertex2f(v2d->tot.xmax, v2d->tot.ymin);
|
||||
}
|
||||
}
|
||||
else if (draw_backdrop) {
|
||||
float aspect = BLI_rcti_size_x(&ar->winrct) / (float)BLI_rcti_size_y(&ar->winrct);
|
||||
float image_aspect = viewrectx/viewrecty;
|
||||
float imagex, imagey;
|
||||
|
||||
if (aspect >= image_aspect) {
|
||||
imagex = image_aspect/aspect;
|
||||
imagey = 1.0f;
|
||||
}
|
||||
else {
|
||||
imagex = 1.0f;
|
||||
imagey = aspect/image_aspect;
|
||||
}
|
||||
|
||||
glTexCoord2f(0.0f, 0.0f); glVertex2f(-imagex, -imagey);
|
||||
glTexCoord2f(0.0f, 1.0f); glVertex2f(-imagex, imagey);
|
||||
glTexCoord2f(1.0f, 1.0f); glVertex2f(imagex, imagey);
|
||||
glTexCoord2f(1.0f, 0.0f); glVertex2f(imagex, -imagey);
|
||||
}
|
||||
else {
|
||||
glTexCoord2f(0.0f, 0.0f); glVertex2f(v2d->tot.xmin, v2d->tot.ymin);
|
||||
glTexCoord2f(0.0f, 1.0f); glVertex2f(v2d->tot.xmin, v2d->tot.ymax);
|
||||
@ -1190,6 +1123,15 @@ void draw_image_seq(const bContext *C, Scene *scene, ARegion *ar, SpaceSeq *sseq
|
||||
glTexCoord2f(1.0f, 0.0f); glVertex2f(v2d->tot.xmax, v2d->tot.ymin);
|
||||
}
|
||||
glEnd();
|
||||
|
||||
if (draw_backdrop) {
|
||||
glPopMatrix();
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glPopMatrix();
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
|
||||
}
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, last_texid);
|
||||
glDisable(GL_TEXTURE_2D);
|
||||
if (sseq->mainb == SEQ_DRAW_IMG_IMBUF && sseq->flag & SEQ_USE_ALPHA)
|
||||
@ -1199,6 +1141,16 @@ void draw_image_seq(const bContext *C, Scene *scene, ARegion *ar, SpaceSeq *sseq
|
||||
if (glsl_used)
|
||||
IMB_colormanagement_finish_glsl_draw();
|
||||
|
||||
if (cache_handle)
|
||||
IMB_display_buffer_release(cache_handle);
|
||||
|
||||
if (!scope)
|
||||
IMB_freeImBuf(ibuf);
|
||||
|
||||
if (draw_backdrop) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (sseq->mainb == SEQ_DRAW_IMG_IMBUF) {
|
||||
|
||||
float x1 = v2d->tot.xmin;
|
||||
@ -1248,9 +1200,6 @@ void draw_image_seq(const bContext *C, Scene *scene, ARegion *ar, SpaceSeq *sseq
|
||||
ED_gpencil_draw_2dimage(C);
|
||||
}
|
||||
}
|
||||
|
||||
if (!scope)
|
||||
IMB_freeImBuf(ibuf);
|
||||
|
||||
/* ortho at pixel level */
|
||||
UI_view2d_view_restore(C);
|
||||
@ -1287,9 +1236,6 @@ void draw_image_seq(const bContext *C, Scene *scene, ARegion *ar, SpaceSeq *sseq
|
||||
NULL, C);
|
||||
}
|
||||
}
|
||||
|
||||
if (cache_handle)
|
||||
IMB_display_buffer_release(cache_handle);
|
||||
}
|
||||
|
||||
#if 0
|
||||
@ -1366,6 +1312,7 @@ static void draw_seq_strips(const bContext *C, Editing *ed, ARegion *ar)
|
||||
{
|
||||
Scene *scene = CTX_data_scene(C);
|
||||
View2D *v2d = &ar->v2d;
|
||||
SpaceSeq *sseq = CTX_wm_space_seq(C);
|
||||
Sequence *last_seq = BKE_sequencer_active_get(scene);
|
||||
int sel = 0, j;
|
||||
float pixelx = BLI_rctf_size_x(&v2d->cur) / BLI_rcti_size_x(&v2d->mask);
|
||||
@ -1386,7 +1333,7 @@ static void draw_seq_strips(const bContext *C, Editing *ed, ARegion *ar)
|
||||
else if (seq->machine > v2d->cur.ymax) continue;
|
||||
|
||||
/* strip passed all tests unscathed... so draw it now */
|
||||
draw_seq_strip(scene, ar, seq, outline_tint, pixelx);
|
||||
draw_seq_strip(C, sseq, scene, ar, seq, outline_tint, pixelx);
|
||||
}
|
||||
|
||||
/* draw selected next time round */
|
||||
@ -1395,7 +1342,7 @@ static void draw_seq_strips(const bContext *C, Editing *ed, ARegion *ar)
|
||||
|
||||
/* draw the last selected last (i.e. 'active' in other parts of Blender), removes some overlapping error */
|
||||
if (last_seq)
|
||||
draw_seq_strip(scene, ar, last_seq, 120, pixelx);
|
||||
draw_seq_strip(C, sseq, scene, ar, last_seq, 120, pixelx);
|
||||
}
|
||||
|
||||
static void seq_draw_sfra_efra(Scene *scene, View2D *v2d)
|
||||
@ -1473,6 +1420,12 @@ void draw_timeline_seq(const bContext *C, ARegion *ar)
|
||||
// NOTE: the gridlines are currently spaced every 25 frames, which is only fine for 25 fps, but maybe not for 30...
|
||||
UI_view2d_constant_grid_draw(v2d);
|
||||
|
||||
if (sseq->draw_flag & SEQ_DRAW_BACKDROP) {
|
||||
draw_image_seq(C, scene, ar, sseq, scene->r.cfra, 0, false, true);
|
||||
UI_SetTheme(SPACE_SEQ, RGN_TYPE_WINDOW);
|
||||
UI_view2d_view_ortho(v2d);
|
||||
}
|
||||
|
||||
ED_region_draw_cb_draw(C, ar, REGION_DRAW_PRE_VIEW);
|
||||
|
||||
seq_draw_sfra_efra(scene, v2d);
|
||||
|
@ -62,8 +62,13 @@
|
||||
#include "ED_screen.h"
|
||||
#include "ED_transform.h"
|
||||
#include "ED_sequencer.h"
|
||||
#include "ED_space_api.h"
|
||||
|
||||
#include "UI_view2d.h"
|
||||
#include "UI_resources.h"
|
||||
|
||||
#include "GL/glew.h"
|
||||
#include "BIF_glutil.h"
|
||||
|
||||
/* own include */
|
||||
#include "sequencer_intern.h"
|
||||
@ -1231,7 +1236,6 @@ void SEQUENCER_OT_snap(struct wmOperatorType *ot)
|
||||
RNA_def_int(ot->srna, "frame", 0, INT_MIN, INT_MAX, "Frame", "Frame where selected strips will be snapped", INT_MIN, INT_MAX);
|
||||
}
|
||||
|
||||
|
||||
typedef struct SlipData {
|
||||
int init_mouse[2];
|
||||
float init_mouseloc[2];
|
||||
@ -1241,6 +1245,7 @@ typedef struct SlipData {
|
||||
int num_seq;
|
||||
bool slow;
|
||||
int slow_offset; /* offset at the point where offset was turned on */
|
||||
void *draw_handle;
|
||||
} SlipData;
|
||||
|
||||
static void transseq_backup(TransSeq *ts, Sequence *seq)
|
||||
@ -1274,15 +1279,129 @@ static void transseq_restore(TransSeq *ts, Sequence *seq)
|
||||
seq->len = ts->len;
|
||||
}
|
||||
|
||||
static int slip_add_sequences_rec(ListBase *seqbasep, Sequence **seq_array, bool *trim, int offset, bool first_level)
|
||||
static void draw_slip_extensions(const bContext *C, ARegion *ar, void *data)
|
||||
{
|
||||
Scene *scene = CTX_data_scene(C);
|
||||
float x1, x2, y1, y2, pixely, a;
|
||||
unsigned char col[3], blendcol[3];
|
||||
View2D *v2d = &ar->v2d;
|
||||
SlipData *td = data;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < td->num_seq; i++) {
|
||||
Sequence *seq = td->seq_array[i];
|
||||
|
||||
if ((seq->type != SEQ_TYPE_META) && td->trim[i]) {
|
||||
|
||||
x1 = seq->startdisp;
|
||||
x2 = seq->enddisp;
|
||||
|
||||
y1 = seq->machine + SEQ_STRIP_OFSBOTTOM;
|
||||
y2 = seq->machine + SEQ_STRIP_OFSTOP;
|
||||
|
||||
pixely = BLI_rctf_size_y(&v2d->cur) / BLI_rcti_size_y(&v2d->mask);
|
||||
|
||||
if (pixely <= 0) return; /* can happen when the view is split/resized */
|
||||
|
||||
blendcol[0] = blendcol[1] = blendcol[2] = 120;
|
||||
|
||||
if (seq->startofs) {
|
||||
glEnable(GL_BLEND);
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
|
||||
color3ubv_from_seq(scene, seq, col);
|
||||
|
||||
if (seq->flag & SELECT) {
|
||||
UI_GetColorPtrBlendShade3ubv(col, blendcol, col, 0.3, -40);
|
||||
glColor4ub(col[0], col[1], col[2], 170);
|
||||
}
|
||||
else {
|
||||
UI_GetColorPtrBlendShade3ubv(col, blendcol, col, 0.6, 0);
|
||||
glColor4ub(col[0], col[1], col[2], 110);
|
||||
}
|
||||
|
||||
glRectf((float)(seq->start), y1 - SEQ_STRIP_OFSBOTTOM, x1, y1);
|
||||
|
||||
if (seq->flag & SELECT) glColor4ub(col[0], col[1], col[2], 255);
|
||||
else glColor4ub(col[0], col[1], col[2], 160);
|
||||
|
||||
fdrawbox((float)(seq->start), y1 - SEQ_STRIP_OFSBOTTOM, x1, y1); //outline
|
||||
|
||||
glDisable(GL_BLEND);
|
||||
}
|
||||
if (seq->endofs) {
|
||||
glEnable(GL_BLEND);
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
|
||||
color3ubv_from_seq(scene, seq, col);
|
||||
|
||||
if (seq->flag & SELECT) {
|
||||
UI_GetColorPtrBlendShade3ubv(col, blendcol, col, 0.3, -40);
|
||||
glColor4ub(col[0], col[1], col[2], 170);
|
||||
}
|
||||
else {
|
||||
UI_GetColorPtrBlendShade3ubv(col, blendcol, col, 0.6, 0);
|
||||
glColor4ub(col[0], col[1], col[2], 110);
|
||||
}
|
||||
|
||||
glRectf(x2, y2, (float)(seq->start + seq->len), y2 + SEQ_STRIP_OFSBOTTOM);
|
||||
|
||||
if (seq->flag & SELECT) glColor4ub(col[0], col[1], col[2], 255);
|
||||
else glColor4ub(col[0], col[1], col[2], 160);
|
||||
|
||||
fdrawbox(x2, y2, (float)(seq->start + seq->len), y2 + SEQ_STRIP_OFSBOTTOM); //outline
|
||||
|
||||
glDisable(GL_BLEND);
|
||||
}
|
||||
if (seq->startstill) {
|
||||
color3ubv_from_seq(scene, seq, col);
|
||||
UI_GetColorPtrBlendShade3ubv(col, blendcol, col, 0.75, 40);
|
||||
glColor3ubv((GLubyte *)col);
|
||||
|
||||
draw_shadedstrip(seq, col, x1, y1, (float)(seq->start), y2);
|
||||
|
||||
/* feint pinstripes, helps see exactly which is extended and which isn't,
|
||||
* especially when the extension is very small */
|
||||
if (seq->flag & SELECT) UI_GetColorPtrBlendShade3ubv(col, col, col, 0.0, 24);
|
||||
else UI_GetColorPtrShade3ubv(col, col, -16);
|
||||
|
||||
glColor3ubv((GLubyte *)col);
|
||||
|
||||
for (a = y1; a < y2; a += pixely * 2.0f) {
|
||||
fdrawline(x1, a, (float)(seq->start), a);
|
||||
}
|
||||
}
|
||||
if (seq->endstill) {
|
||||
color3ubv_from_seq(scene, seq, col);
|
||||
UI_GetColorPtrBlendShade3ubv(col, blendcol, col, 0.75, 40);
|
||||
glColor3ubv((GLubyte *)col);
|
||||
|
||||
draw_shadedstrip(seq, col, (float)(seq->start + seq->len), y1, x2, y2);
|
||||
|
||||
/* feint pinstripes, helps see exactly which is extended and which isn't,
|
||||
* especially when the extension is very small */
|
||||
if (seq->flag & SELECT) UI_GetColorPtrShade3ubv(col, col, 24);
|
||||
else UI_GetColorPtrShade3ubv(col, col, -16);
|
||||
|
||||
glColor3ubv((GLubyte *)col);
|
||||
|
||||
for (a = y1; a < y2; a += pixely * 2.0f) {
|
||||
fdrawline((float)(seq->start + seq->len), a, x2, a);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static int slip_add_sequences_rec(ListBase *seqbasep, Sequence **seq_array, bool *trim, int offset, bool do_trim)
|
||||
{
|
||||
Sequence *seq;
|
||||
int num_items = 0;
|
||||
|
||||
for (seq = seqbasep->first; seq; seq = seq->next) {
|
||||
if (!first_level || (!(seq->type & SEQ_TYPE_EFFECT) && (seq->flag & SELECT))) {
|
||||
if (!do_trim || (!(seq->type & SEQ_TYPE_EFFECT) && (seq->flag & SELECT))) {
|
||||
seq_array[offset + num_items] = seq;
|
||||
trim[offset + num_items] = first_level;
|
||||
trim[offset + num_items] = do_trim;
|
||||
num_items++;
|
||||
|
||||
if (seq->type == SEQ_TYPE_META) {
|
||||
@ -1322,6 +1441,7 @@ static int sequencer_slip_invoke(bContext *C, wmOperator *op, const wmEvent *eve
|
||||
SlipData *data;
|
||||
Scene *scene = CTX_data_scene(C);
|
||||
Editing *ed = BKE_sequencer_editing_get(scene, false);
|
||||
ARegion *ar = CTX_wm_region(C);
|
||||
float mouseloc[2];
|
||||
int num_seq, i;
|
||||
View2D *v2d = UI_view2d_fromcontext(C);
|
||||
@ -1344,6 +1464,8 @@ static int sequencer_slip_invoke(bContext *C, wmOperator *op, const wmEvent *eve
|
||||
transseq_backup(data->ts + i, data->seq_array[i]);
|
||||
}
|
||||
|
||||
data->draw_handle = ED_region_draw_cb_activate(ar->type, draw_slip_extensions, data, REGION_DRAW_POST_VIEW);
|
||||
|
||||
UI_view2d_region_to_view(v2d, event->mval[0], event->mval[1], &mouseloc[0], &mouseloc[1]);
|
||||
|
||||
copy_v2_v2_int(data->init_mouse, event->mval);
|
||||
@ -1353,6 +1475,9 @@ static int sequencer_slip_invoke(bContext *C, wmOperator *op, const wmEvent *eve
|
||||
|
||||
WM_event_add_modal_handler(C, op);
|
||||
|
||||
/* notify so we draw extensions immediately */
|
||||
WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene);
|
||||
|
||||
return OPERATOR_RUNNING_MODAL;
|
||||
}
|
||||
|
||||
@ -1463,6 +1588,7 @@ static int sequencer_slip_modal(bContext *C, wmOperator *op, const wmEvent *even
|
||||
Scene *scene = CTX_data_scene(C);
|
||||
SlipData *data = (SlipData *)op->customdata;
|
||||
ScrArea *sa = CTX_wm_area(C);
|
||||
ARegion *ar = CTX_wm_region(C);
|
||||
|
||||
switch (event->type) {
|
||||
case MOUSEMOVE:
|
||||
@ -1504,6 +1630,7 @@ static int sequencer_slip_modal(bContext *C, wmOperator *op, const wmEvent *even
|
||||
|
||||
case LEFTMOUSE:
|
||||
{
|
||||
ED_region_draw_cb_exit(ar->type, data->draw_handle);
|
||||
MEM_freeN(data->seq_array);
|
||||
MEM_freeN(data->trim);
|
||||
MEM_freeN(data->ts);
|
||||
@ -1532,6 +1659,8 @@ static int sequencer_slip_modal(bContext *C, wmOperator *op, const wmEvent *even
|
||||
BKE_sequence_calc(scene, seq);
|
||||
}
|
||||
|
||||
ED_region_draw_cb_exit(ar->type, data->draw_handle);
|
||||
|
||||
MEM_freeN(data->seq_array);
|
||||
MEM_freeN(data->ts);
|
||||
MEM_freeN(data->trim);
|
||||
@ -1587,7 +1716,6 @@ void SEQUENCER_OT_slip(struct wmOperatorType *ot)
|
||||
INT32_MIN, INT32_MAX);
|
||||
}
|
||||
|
||||
|
||||
/* mute operator */
|
||||
static int sequencer_mute_exec(bContext *C, wmOperator *op)
|
||||
{
|
||||
@ -2810,74 +2938,13 @@ void SEQUENCER_OT_view_selected(wmOperatorType *ot)
|
||||
ot->flag = OPTYPE_REGISTER;
|
||||
}
|
||||
|
||||
|
||||
static int find_next_prev_edit(Scene *scene, int cfra,
|
||||
const short side,
|
||||
const bool do_skip_mute, const bool do_center)
|
||||
{
|
||||
Editing *ed = BKE_sequencer_editing_get(scene, false);
|
||||
Sequence *seq;
|
||||
|
||||
int dist, best_dist, best_frame = cfra;
|
||||
int seq_frames[2], seq_frames_tot;
|
||||
|
||||
best_dist = MAXFRAME * 2;
|
||||
|
||||
if (ed == NULL) return cfra;
|
||||
|
||||
for (seq = ed->seqbasep->first; seq; seq = seq->next) {
|
||||
int i;
|
||||
|
||||
if (do_skip_mute && (seq->flag & SEQ_MUTE)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (do_center) {
|
||||
seq_frames[0] = (seq->startdisp + seq->enddisp) / 2;
|
||||
seq_frames_tot = 1;
|
||||
}
|
||||
else {
|
||||
seq_frames[0] = seq->startdisp;
|
||||
seq_frames[1] = seq->enddisp;
|
||||
|
||||
seq_frames_tot = 2;
|
||||
}
|
||||
|
||||
for (i = 0; i < seq_frames_tot; i++) {
|
||||
const int seq_frame = seq_frames[i];
|
||||
|
||||
dist = MAXFRAME * 2;
|
||||
|
||||
switch (side) {
|
||||
case SEQ_SIDE_LEFT:
|
||||
if (seq_frame < cfra) {
|
||||
dist = cfra - seq_frame;
|
||||
}
|
||||
break;
|
||||
case SEQ_SIDE_RIGHT:
|
||||
if (seq_frame > cfra) {
|
||||
dist = seq_frame - cfra;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (dist < best_dist) {
|
||||
best_frame = seq_frame;
|
||||
best_dist = dist;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return best_frame;
|
||||
}
|
||||
|
||||
static bool strip_jump_internal(Scene *scene,
|
||||
const short side,
|
||||
const bool do_skip_mute, const bool do_center)
|
||||
{
|
||||
bool changed = false;
|
||||
int cfra = CFRA;
|
||||
int nfra = find_next_prev_edit(scene, cfra, side, do_skip_mute, do_center);
|
||||
int nfra = BKE_sequencer_find_next_prev_edit(scene, cfra, side, do_skip_mute, do_center, false);
|
||||
|
||||
if (nfra != cfra) {
|
||||
CFRA = nfra;
|
||||
@ -3623,4 +3690,3 @@ void SEQUENCER_OT_change_path(struct wmOperatorType *ot)
|
||||
WM_FILESEL_DIRECTORY | WM_FILESEL_RELPATH | WM_FILESEL_FILEPATH | WM_FILESEL_FILES,
|
||||
FILE_DEFAULTDISPLAY);
|
||||
}
|
||||
|
||||
|
@ -45,6 +45,7 @@ struct ARegion;
|
||||
struct ARegionType;
|
||||
struct Scene;
|
||||
struct Main;
|
||||
struct SequencePreview;
|
||||
|
||||
/* space_sequencer.c */
|
||||
struct ARegion *sequencer_has_buttons_region(struct ScrArea *sa);
|
||||
@ -52,7 +53,9 @@ struct ARegion *sequencer_has_buttons_region(struct ScrArea *sa);
|
||||
|
||||
/* sequencer_draw.c */
|
||||
void draw_timeline_seq(const struct bContext *C, struct ARegion *ar);
|
||||
void draw_image_seq(const struct bContext *C, struct Scene *scene, struct ARegion *ar, struct SpaceSeq *sseq, int cfra, int offset, bool draw_overlay);
|
||||
void draw_image_seq(const struct bContext *C, struct Scene *scene, struct ARegion *ar, struct SpaceSeq *sseq, int cfra, int offset, bool draw_overlay, bool draw_backdrop);
|
||||
void color3ubv_from_seq(struct Scene *curscene, struct Sequence *seq, unsigned char col[3]);
|
||||
void draw_shadedstrip(struct Sequence *seq, unsigned char col[3], float x1, float y1, float x2, float y2);
|
||||
|
||||
/* UNUSED */
|
||||
// void seq_reset_imageofs(struct SpaceSeq *sseq);
|
||||
@ -150,13 +153,6 @@ void SEQUENCER_OT_sound_strip_add(struct wmOperatorType *ot);
|
||||
void SEQUENCER_OT_image_strip_add(struct wmOperatorType *ot);
|
||||
void SEQUENCER_OT_effect_strip_add(struct wmOperatorType *ot);
|
||||
|
||||
/* RNA enums, just to be more readable */
|
||||
enum {
|
||||
SEQ_SIDE_NONE = 0,
|
||||
SEQ_SIDE_LEFT,
|
||||
SEQ_SIDE_RIGHT,
|
||||
SEQ_SIDE_BOTH
|
||||
};
|
||||
enum {
|
||||
SEQ_CUT_SOFT,
|
||||
SEQ_CUT_HARD
|
||||
@ -199,5 +195,8 @@ void SEQUENCER_OT_strip_modifier_move(struct wmOperatorType *ot);
|
||||
/* sequencer_view.c */
|
||||
void SEQUENCER_OT_sample(struct wmOperatorType *ot);
|
||||
|
||||
/* sequencer_preview.c */
|
||||
void sequencer_preview_add_sound(const struct bContext *C, struct Sequence *seq);
|
||||
|
||||
#endif /* __SEQUENCER_INTERN_H__ */
|
||||
|
||||
|
@ -40,6 +40,8 @@
|
||||
#include "ED_markers.h"
|
||||
#include "ED_transform.h" /* transform keymap */
|
||||
|
||||
#include "BKE_sequencer.h"
|
||||
|
||||
#include "sequencer_intern.h"
|
||||
|
||||
|
||||
|
172
source/blender/editors/space_sequencer/sequencer_preview.c
Normal file
172
source/blender/editors/space_sequencer/sequencer_preview.c
Normal file
@ -0,0 +1,172 @@
|
||||
/*
|
||||
* ***** BEGIN GPL LICENSE BLOCK *****
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Contributor(s): Blender Foundation, 2003-2009, Antony Riakiotakis
|
||||
*
|
||||
* ***** END GPL LICENSE BLOCK *****
|
||||
*/
|
||||
|
||||
/** \file blender/editors/space_sequencer/sequencer_preview.c
|
||||
* \ingroup spseq
|
||||
*/
|
||||
|
||||
#include "DNA_sequence_types.h"
|
||||
#include "DNA_sound_types.h"
|
||||
|
||||
#include "BLI_listbase.h"
|
||||
#include "BLI_threads.h"
|
||||
|
||||
#include "BKE_sound.h"
|
||||
#include "BKE_context.h"
|
||||
#include "BKE_global.h"
|
||||
|
||||
#include "WM_api.h"
|
||||
#include "WM_types.h"
|
||||
|
||||
#include "ED_screen.h"
|
||||
|
||||
#include "MEM_guardedalloc.h"
|
||||
|
||||
#include "sequencer_intern.h"
|
||||
|
||||
typedef struct PreviewJob {
|
||||
ListBase previews;
|
||||
ThreadMutex *mutex;
|
||||
Scene *scene;
|
||||
int total;
|
||||
int processed;
|
||||
} PreviewJob;
|
||||
|
||||
typedef struct PreviewJobAudio {
|
||||
struct PreviewJobAudio *next, *prev;
|
||||
bSound *sound;
|
||||
int lr; /* sample left or right */
|
||||
int startframe;
|
||||
bool waveform; /* reload sound or waveform */
|
||||
} PreviewJobAudio;
|
||||
|
||||
static void free_preview_job(void *data)
|
||||
{
|
||||
PreviewJob *pj = (PreviewJob *)data;
|
||||
|
||||
BLI_mutex_free(pj->mutex);
|
||||
BLI_freelistN(&pj->previews);
|
||||
MEM_freeN(pj);
|
||||
}
|
||||
|
||||
/* only this runs inside thread */
|
||||
static void preview_startjob(void *data, short *stop, short *do_update, float *progress)
|
||||
{
|
||||
PreviewJob *pj = data;
|
||||
PreviewJobAudio *previewjb;
|
||||
|
||||
BLI_mutex_lock(pj->mutex);
|
||||
previewjb = pj->previews.first;
|
||||
BLI_mutex_unlock(pj->mutex);
|
||||
|
||||
while (previewjb) {
|
||||
PreviewJobAudio *preview_next;
|
||||
bSound *sound = previewjb->sound;
|
||||
|
||||
sound_read_waveform(sound, true, stop);
|
||||
|
||||
if (*stop || G.is_break) {
|
||||
BLI_mutex_lock(pj->mutex);
|
||||
previewjb = previewjb->next;
|
||||
BLI_mutex_unlock(pj->mutex);
|
||||
while (previewjb) {
|
||||
sound = previewjb->sound;
|
||||
|
||||
/* make sure we cleanup the loading flag! */
|
||||
BLI_mutex_lock(sound->mutex);
|
||||
sound->flags &= ~SOUND_FLAGS_WAVEFORM_LOADING;
|
||||
BLI_mutex_unlock(sound->mutex);
|
||||
|
||||
BLI_mutex_lock(pj->mutex);
|
||||
previewjb = previewjb->next;
|
||||
BLI_mutex_unlock(pj->mutex);
|
||||
}
|
||||
|
||||
BLI_mutex_lock(pj->mutex);
|
||||
BLI_freelistN(&pj->previews);
|
||||
pj->total = 0;
|
||||
pj->processed = 0;
|
||||
BLI_mutex_unlock(pj->mutex);
|
||||
break;
|
||||
}
|
||||
|
||||
BLI_mutex_lock(pj->mutex);
|
||||
preview_next = previewjb->next;
|
||||
BLI_freelinkN(&pj->previews, previewjb);
|
||||
previewjb = preview_next;
|
||||
pj->processed++;
|
||||
*progress = (pj->total > 0) ? (float)pj->processed / (float)pj->total : 1.0;
|
||||
*do_update = true;
|
||||
BLI_mutex_unlock(pj->mutex);
|
||||
}
|
||||
}
|
||||
|
||||
static void preview_endjob(void *data)
|
||||
{
|
||||
PreviewJob *pj = data;
|
||||
|
||||
WM_main_add_notifier(NC_SCENE | ND_SEQUENCER, pj->scene);
|
||||
}
|
||||
|
||||
|
||||
void sequencer_preview_add_sound(const bContext *C, Sequence *seq)
|
||||
{
|
||||
/* first, get the preview job, if it exists */
|
||||
wmJob *wm_job;
|
||||
PreviewJob *pj;
|
||||
ScrArea *sa = CTX_wm_area(C);
|
||||
PreviewJobAudio *audiojob = MEM_callocN(sizeof(PreviewJobAudio), "preview_audio");
|
||||
wm_job = WM_jobs_get(CTX_wm_manager(C), CTX_wm_window(C), sa, "Strip Previews",
|
||||
WM_JOB_PROGRESS, WM_JOB_TYPE_SEQ_BUILD_PREVIEW);
|
||||
|
||||
pj = WM_jobs_customdata_get(wm_job);
|
||||
|
||||
if (!pj) {
|
||||
pj = MEM_callocN(sizeof(PreviewJob), "preview rebuild job");
|
||||
|
||||
pj->mutex = BLI_mutex_alloc();
|
||||
pj->scene = CTX_data_scene(C);
|
||||
|
||||
WM_jobs_customdata_set(wm_job, pj, free_preview_job);
|
||||
WM_jobs_timer(wm_job, 0.1, NC_SCENE | ND_SEQUENCER, NC_SCENE | ND_SEQUENCER);
|
||||
WM_jobs_callbacks(wm_job, preview_startjob, NULL, NULL, preview_endjob);
|
||||
}
|
||||
|
||||
/* attempt to lock mutex of job here */
|
||||
|
||||
audiojob->sound = seq->sound;
|
||||
|
||||
BLI_mutex_lock(pj->mutex);
|
||||
BLI_addtail(&pj->previews, audiojob);
|
||||
pj->total++;
|
||||
BLI_mutex_unlock(pj->mutex);
|
||||
|
||||
if (!WM_jobs_is_running(wm_job)) {
|
||||
G.is_break = false;
|
||||
WM_jobs_start(CTX_wm_manager(C), wm_job);
|
||||
}
|
||||
|
||||
ED_area_tag_redraw(sa);
|
||||
}
|
@ -559,7 +559,7 @@ static void sequencer_preview_area_draw(const bContext *C, ARegion *ar)
|
||||
if (sseq->mainb == SEQ_DRAW_SEQUENCE) sseq->mainb = SEQ_DRAW_IMG_IMBUF;
|
||||
|
||||
if (!show_split || sseq->overlay_type != SEQ_DRAW_OVERLAY_REFERENCE)
|
||||
draw_image_seq(C, scene, ar, sseq, scene->r.cfra, 0, false);
|
||||
draw_image_seq(C, scene, ar, sseq, scene->r.cfra, 0, false, false);
|
||||
|
||||
if (show_split && sseq->overlay_type != SEQ_DRAW_OVERLAY_CURRENT) {
|
||||
int over_cfra;
|
||||
@ -570,7 +570,7 @@ static void sequencer_preview_area_draw(const bContext *C, ARegion *ar)
|
||||
over_cfra = scene->r.cfra + scene->ed->over_ofs;
|
||||
|
||||
if (over_cfra != scene->r.cfra || sseq->overlay_type != SEQ_DRAW_OVERLAY_RECT)
|
||||
draw_image_seq(C, scene, ar, sseq, scene->r.cfra, over_cfra - scene->r.cfra, true);
|
||||
draw_image_seq(C, scene, ar, sseq, scene->r.cfra, over_cfra - scene->r.cfra, true, false);
|
||||
}
|
||||
|
||||
if ((U.uiflag & USER_SHOW_FPS) && ED_screen_animation_playing(wm)) {
|
||||
|
@ -7126,10 +7126,11 @@ static void headerSeqSlide(TransInfo *t, float val[2], char str[MAX_INFO_LEN])
|
||||
WM_bool_as_string((t->flag & T_ALT_TRANSFORM) != 0));
|
||||
}
|
||||
|
||||
static void applySeqSlideValue(TransInfo *t, const float val[2])
|
||||
static void applySeqSlideValue(TransInfo *t, const float val[2], int frame)
|
||||
{
|
||||
TransData *td = t->data;
|
||||
int i;
|
||||
TransSeq *ts = t->customData;
|
||||
|
||||
for (i = 0; i < t->total; i++, td++) {
|
||||
float tvec[2];
|
||||
@ -7144,15 +7145,21 @@ static void applySeqSlideValue(TransInfo *t, const float val[2])
|
||||
|
||||
mul_v2_fl(tvec, td->factor);
|
||||
|
||||
td->loc[0] = td->iloc[0] + tvec[0];
|
||||
if (t->modifiers & MOD_SNAP_INVERT) {
|
||||
td->loc[0] = frame + td->factor * (td->iloc[0] - ts->min);
|
||||
}
|
||||
else {
|
||||
td->loc[0] = td->iloc[0] + tvec[0];
|
||||
}
|
||||
|
||||
td->loc[1] = td->iloc[1] + tvec[1];
|
||||
}
|
||||
}
|
||||
|
||||
static void applySeqSlide(TransInfo *t, const int UNUSED(mval[2]))
|
||||
static void applySeqSlide(TransInfo *t, const int mval[2])
|
||||
{
|
||||
char str[MAX_INFO_LEN];
|
||||
|
||||
int snap_frame = 0;
|
||||
if (t->con.mode & CON_APPLY) {
|
||||
float pvec[3] = {0.0f, 0.0f, 0.0f};
|
||||
float tvec[3];
|
||||
@ -7160,7 +7167,8 @@ static void applySeqSlide(TransInfo *t, const int UNUSED(mval[2]))
|
||||
copy_v3_v3(t->values, tvec);
|
||||
}
|
||||
else {
|
||||
snapGridIncrement(t, t->values);
|
||||
snap_frame = snapSequenceBounds(t, mval);
|
||||
// snapGridIncrement(t, t->values);
|
||||
applyNumInput(&t->num, t->values);
|
||||
}
|
||||
|
||||
@ -7168,7 +7176,7 @@ static void applySeqSlide(TransInfo *t, const int UNUSED(mval[2]))
|
||||
t->values[1] = floor(t->values[1] + 0.5f);
|
||||
|
||||
headerSeqSlide(t, t->values, str);
|
||||
applySeqSlideValue(t, t->values);
|
||||
applySeqSlideValue(t, t->values, snap_frame);
|
||||
|
||||
recalcData(t);
|
||||
|
||||
|
@ -173,6 +173,13 @@ typedef struct TransDataSeq {
|
||||
|
||||
} TransDataSeq;
|
||||
|
||||
typedef struct TransSeq {
|
||||
TransDataSeq *tdseq;
|
||||
int min;
|
||||
int max;
|
||||
bool snap_left;
|
||||
} TransSeq;
|
||||
|
||||
/* for NLA transform (stored in td->extra pointer) */
|
||||
typedef struct TransDataNla {
|
||||
ID *id; /* ID-block NLA-data is attached to */
|
||||
@ -588,6 +595,8 @@ typedef enum {
|
||||
void snapGridIncrement(TransInfo *t, float *val);
|
||||
void snapGridIncrementAction(TransInfo *t, float *val, GearsType action);
|
||||
|
||||
int snapSequenceBounds(TransInfo *t, const int mval[2]);
|
||||
|
||||
bool activeSnap(TransInfo *t);
|
||||
bool validSnap(TransInfo *t);
|
||||
|
||||
|
@ -4528,10 +4528,47 @@ static int SeqToTransData_Recursive(TransInfo *t, ListBase *seqbase, TransData *
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return tot;
|
||||
}
|
||||
|
||||
|
||||
static void SeqTransDataBounds(TransInfo *t, ListBase *seqbase, TransSeq *ts)
|
||||
{
|
||||
Sequence *seq;
|
||||
int recursive, count, flag;
|
||||
int max = INT32_MIN, min = INT32_MAX;
|
||||
|
||||
for (seq = seqbase->first; seq; seq = seq->next) {
|
||||
|
||||
/* just to get the flag since there are corner cases where this isn't totally obvious */
|
||||
SeqTransInfo(t, seq, &recursive, &count, &flag);
|
||||
|
||||
/* use 'flag' which is derived from seq->flag but modified for special cases */
|
||||
if (flag & SELECT) {
|
||||
if (flag & (SEQ_LEFTSEL | SEQ_RIGHTSEL)) {
|
||||
if (flag & SEQ_LEFTSEL) {
|
||||
min = min_ii(seq->startdisp, min);
|
||||
max = max_ii(seq->startdisp, max);
|
||||
}
|
||||
if (flag & SEQ_RIGHTSEL) {
|
||||
min = min_ii(seq->enddisp, min);
|
||||
max = max_ii(seq->enddisp, max);
|
||||
}
|
||||
}
|
||||
else {
|
||||
min = min_ii(seq->startdisp, min);
|
||||
max = max_ii(seq->enddisp, max);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (ts) {
|
||||
ts->max = max;
|
||||
ts->min = min;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void freeSeqData(TransInfo *t)
|
||||
{
|
||||
Editing *ed = BKE_sequencer_editing_get(t->scene, false);
|
||||
@ -4694,6 +4731,8 @@ static void freeSeqData(TransInfo *t)
|
||||
}
|
||||
|
||||
if ((t->customData != NULL) && (t->flag & T_FREE_CUSTOMDATA)) {
|
||||
TransSeq *ts = t->customData;
|
||||
MEM_freeN(ts->tdseq);
|
||||
MEM_freeN(t->customData);
|
||||
t->customData = NULL;
|
||||
}
|
||||
@ -4713,6 +4752,8 @@ static void createTransSeqData(bContext *C, TransInfo *t)
|
||||
TransData *td = NULL;
|
||||
TransData2D *td2d = NULL;
|
||||
TransDataSeq *tdsq = NULL;
|
||||
TransSeq *ts = NULL;
|
||||
float xmouse, ymouse;
|
||||
|
||||
int count = 0;
|
||||
|
||||
@ -4723,12 +4764,11 @@ static void createTransSeqData(bContext *C, TransInfo *t)
|
||||
|
||||
t->customFree = freeSeqData;
|
||||
|
||||
UI_view2d_region_to_view(v2d, t->imval[0], t->imval[1], &xmouse, &ymouse);
|
||||
|
||||
/* which side of the current frame should be allowed */
|
||||
if (t->mode == TFM_TIME_EXTEND) {
|
||||
/* only side on which mouse is gets transformed */
|
||||
float xmouse, ymouse;
|
||||
|
||||
UI_view2d_region_to_view(v2d, t->imval[0], t->imval[1], &xmouse, &ymouse);
|
||||
t->frame_side = (xmouse > CFRA) ? 'R' : 'L';
|
||||
}
|
||||
else {
|
||||
@ -4768,15 +4808,19 @@ static void createTransSeqData(bContext *C, TransInfo *t)
|
||||
return;
|
||||
}
|
||||
|
||||
t->customData = ts = MEM_mallocN(sizeof(TransSeq), "transseq");
|
||||
td = t->data = MEM_callocN(t->total * sizeof(TransData), "TransSeq TransData");
|
||||
td2d = t->data2d = MEM_callocN(t->total * sizeof(TransData2D), "TransSeq TransData2D");
|
||||
tdsq = t->customData = MEM_callocN(t->total * sizeof(TransDataSeq), "TransSeq TransDataSeq");
|
||||
ts->tdseq = tdsq = MEM_callocN(t->total * sizeof(TransDataSeq), "TransSeq TransDataSeq");
|
||||
t->flag |= T_FREE_CUSTOMDATA;
|
||||
|
||||
|
||||
|
||||
/* loop 2: build transdata array */
|
||||
SeqToTransData_Recursive(t, ed->seqbasep, td, td2d, tdsq);
|
||||
SeqTransDataBounds(t, ed->seqbasep, ts);
|
||||
|
||||
/* set the snap mode based on how close the mouse is at the end/start points */
|
||||
if (abs(xmouse - ts->max) > abs(xmouse - ts->min))
|
||||
ts->snap_left = true;
|
||||
|
||||
#undef XXX_DURIAN_ANIM_TX_HACK
|
||||
}
|
||||
|
@ -59,6 +59,7 @@
|
||||
#include "BKE_anim.h" /* for duplis */
|
||||
#include "BKE_context.h"
|
||||
#include "BKE_editmesh.h"
|
||||
#include "BKE_sequencer.h"
|
||||
#include "BKE_main.h"
|
||||
#include "BKE_tracking.h"
|
||||
|
||||
@ -2430,6 +2431,27 @@ void snapGridIncrement(TransInfo *t, float *val)
|
||||
snapGridIncrementAction(t, val, action);
|
||||
}
|
||||
|
||||
int snapSequenceBounds(TransInfo *t, const int mval[2])
|
||||
{
|
||||
float xmouse, ymouse;
|
||||
int frame;
|
||||
int mframe;
|
||||
TransSeq *ts = t->customData;
|
||||
/* reuse increment, strictly speaking could be another snap mode, but leave as is */
|
||||
if (!(t->modifiers & MOD_SNAP_INVERT))
|
||||
return 0;
|
||||
|
||||
/* convert to frame range */
|
||||
UI_view2d_region_to_view(&t->ar->v2d, mval[0], mval[1], &xmouse, &ymouse);
|
||||
mframe = iroundf(xmouse);
|
||||
/* now find the closest sequence */
|
||||
frame = BKE_sequencer_find_next_prev_edit(t->scene, mframe, SEQ_SIDE_BOTH, true, false, true);
|
||||
|
||||
if (!ts->snap_left)
|
||||
frame = frame - (ts->max - ts->min);
|
||||
|
||||
return frame;
|
||||
}
|
||||
|
||||
static void applyGridIncrement(TransInfo *t, float *val, int max_index, const float fac[3], GearsType action)
|
||||
{
|
||||
|
@ -131,10 +131,11 @@ typedef struct Sequence {
|
||||
|
||||
int flag, type; /*flags bitmap (see below) and the type of sequence*/
|
||||
int len; /* the length of the contents of this strip - before handles are applied */
|
||||
int start, startofs, endofs;
|
||||
int startstill, endstill;
|
||||
int start; /* start frame of contents of strip in absolute frame coordinates. For metastrips start of first strip startdisp */
|
||||
int startofs, endofs; /* frames after the first frame where display starts, frames before the last frame where display ends */
|
||||
int startstill, endstill; /* frames that use the first frame before data begins, frames that use the last frame after data ends */
|
||||
int machine, depth; /*machine - the strip channel, depth - the depth in the sequence when dealing with metastrips */
|
||||
int startdisp, enddisp; /*starting and ending points in the sequence*/
|
||||
int startdisp, enddisp; /* starting and ending points of the strip in the sequence*/
|
||||
float sat;
|
||||
float mul, handsize;
|
||||
|
||||
|
@ -95,6 +95,8 @@ typedef struct bSound {
|
||||
*/
|
||||
void *playback_handle;
|
||||
|
||||
/* mutex for asynchronous loading of sounds */
|
||||
void *mutex;
|
||||
/* XXX unused currently (SOUND_TYPE_LIMITER) */
|
||||
/* float start, end; */
|
||||
} bSound;
|
||||
@ -116,9 +118,10 @@ enum {
|
||||
};
|
||||
|
||||
enum {
|
||||
SOUND_FLAGS_3D = (1 << 3), /* deprecated! used for sound actuator loading */
|
||||
SOUND_FLAGS_CACHING = (1 << 4),
|
||||
SOUND_FLAGS_MONO = (1 << 5),
|
||||
SOUND_FLAGS_3D = (1 << 3), /* deprecated! used for sound actuator loading */
|
||||
SOUND_FLAGS_CACHING = (1 << 4),
|
||||
SOUND_FLAGS_MONO = (1 << 5),
|
||||
SOUND_FLAGS_WAVEFORM_LOADING = (1 << 6),
|
||||
};
|
||||
|
||||
#if (DNA_DEPRECATED_GCC_POISON == 1)
|
||||
|
@ -497,6 +497,8 @@ typedef struct SpaceSeq {
|
||||
float zoom DNA_DEPRECATED; /* deprecated, handled by View2D now */
|
||||
int view; /* see SEQ_VIEW_* below */
|
||||
int overlay_type;
|
||||
int draw_flag; /* overlay an image of the editing on below the strips */
|
||||
int pad;
|
||||
|
||||
struct bGPdata *gpd; /* grease-pencil data */
|
||||
|
||||
@ -513,6 +515,12 @@ typedef enum eSpaceSeq_RegionType {
|
||||
SEQ_DRAW_IMG_HISTOGRAM = 4,
|
||||
} eSpaceSeq_RegionType;
|
||||
|
||||
/* sseq->draw_flag */
|
||||
typedef enum eSpaceSeq_DrawFlag {
|
||||
SEQ_DRAW_BACKDROP = (1 << 0),
|
||||
} eSpaceSeq_DrawFlag;
|
||||
|
||||
|
||||
/* sseq->flag */
|
||||
typedef enum eSpaceSeq_Flag {
|
||||
SEQ_DRAWFRAMES = (1 << 0),
|
||||
@ -522,6 +530,8 @@ typedef enum eSpaceSeq_Flag {
|
||||
SEQ_SHOW_GPENCIL = (1 << 4),
|
||||
SEQ_NO_DRAW_CFRANUM = (1 << 5),
|
||||
SEQ_USE_ALPHA = (1 << 6), /* use RGBA display mode for preview */
|
||||
SEQ_ALL_WAVEFORMS = (1 << 7), /* draw all waveforms */
|
||||
SEQ_NO_WAVEFORMS = (1 << 8), /* draw no waveforms */
|
||||
} eSpaceSeq_Flag;
|
||||
|
||||
/* sseq->view */
|
||||
|
@ -38,6 +38,7 @@
|
||||
|
||||
#include "BKE_sound.h"
|
||||
#include "BKE_context.h"
|
||||
#include "BKE_sequencer.h"
|
||||
|
||||
static void rna_Sound_update(Main *bmain, Scene *UNUSED(scene), PointerRNA *ptr)
|
||||
{
|
||||
@ -59,9 +60,9 @@ static void rna_Sound_caching_set(PointerRNA *ptr, const int value)
|
||||
sound_delete_cache(sound);
|
||||
}
|
||||
|
||||
static void rna_Sound_caching_update(Main *bmain, Scene *UNUSED(scene), PointerRNA *ptr)
|
||||
static void rna_Sound_caching_update(Main *UNUSED(bmain), Scene *scene, PointerRNA *ptr)
|
||||
{
|
||||
sound_update_sequencer(bmain, (bSound *)(ptr->data));
|
||||
BKE_sequencer_update_sound(scene, (bSound *)(ptr->data));
|
||||
}
|
||||
|
||||
#else
|
||||
|
@ -2514,6 +2514,16 @@ static void rna_def_space_sequencer(BlenderRNA *brna)
|
||||
{0, NULL, 0, NULL, NULL}
|
||||
};
|
||||
|
||||
static EnumPropertyItem waveform_type_draw_items[] = {
|
||||
{SEQ_NO_WAVEFORMS, "NO_WAVEFORMS", 0, "Waveforms Off",
|
||||
"No waveforms drawn for all sound strips"},
|
||||
{SEQ_ALL_WAVEFORMS, "ALL_WAVEFORMS", 0, "Waveforms On",
|
||||
"Waveforms drawn for all sound strips"},
|
||||
{0, "DEFAULT_WAVEFORMS", 0, "Use Strip Option",
|
||||
"Waveforms drawn according to strip setting"},
|
||||
{0, NULL, 0, NULL, NULL}
|
||||
};
|
||||
|
||||
srna = RNA_def_struct(brna, "SpaceSequenceEditor", "Space");
|
||||
RNA_def_struct_sdna(srna, "SpaceSeq");
|
||||
RNA_def_struct_ui_text(srna, "Space Sequence Editor", "Sequence editor space data");
|
||||
@ -2583,6 +2593,12 @@ static void rna_def_space_sequencer(BlenderRNA *brna)
|
||||
RNA_def_property_ui_text(prop, "Draw Channels", "Channels of the preview to draw");
|
||||
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_SEQUENCER, NULL);
|
||||
|
||||
prop = RNA_def_property(srna, "waveform_draw_type", PROP_ENUM, PROP_NONE);
|
||||
RNA_def_property_enum_bitflag_sdna(prop, NULL, "flag");
|
||||
RNA_def_property_enum_items(prop, waveform_type_draw_items);
|
||||
RNA_def_property_ui_text(prop, "Waveform Drawing", "How Waveforms are drawn");
|
||||
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_SEQUENCER, NULL);
|
||||
|
||||
prop = RNA_def_property(srna, "draw_overexposed", PROP_INT, PROP_NONE);
|
||||
RNA_def_property_int_sdna(prop, NULL, "zebra");
|
||||
RNA_def_property_ui_text(prop, "Show Overexposed", "Show overexposed areas with zebra stripes");
|
||||
@ -2609,6 +2625,11 @@ static void rna_def_space_sequencer(BlenderRNA *brna)
|
||||
RNA_def_property_enum_items(prop, overlay_type_items);
|
||||
RNA_def_property_ui_text(prop, "Overlay Type", "Overlay draw type");
|
||||
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_SEQUENCER, NULL);
|
||||
|
||||
prop = RNA_def_property(srna, "show_backdrop", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_sdna(prop, NULL, "draw_flag", SEQ_DRAW_BACKDROP);
|
||||
RNA_def_property_ui_text(prop, "Use Backdrop", "Display result under strips");
|
||||
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_SEQUENCER, NULL);
|
||||
}
|
||||
|
||||
static void rna_def_space_text(BlenderRNA *brna)
|
||||
|
@ -398,6 +398,7 @@ enum {
|
||||
WM_JOB_TYPE_CLIP_SOLVE_CAMERA,
|
||||
WM_JOB_TYPE_CLIP_PREFETCH,
|
||||
WM_JOB_TYPE_SEQ_BUILD_PROXY,
|
||||
WM_JOB_TYPE_SEQ_BUILD_PREVIEW,
|
||||
/* add as needed, screencast, seq proxy build
|
||||
* if having hard coded values is a problem */
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user