diff --git a/source/blender/blenkernel/BKE_sequencer.h b/source/blender/blenkernel/BKE_sequencer.h index ebe732d2336..44c116cb1ab 100644 --- a/source/blender/blenkernel/BKE_sequencer.h +++ b/source/blender/blenkernel/BKE_sequencer.h @@ -496,5 +496,6 @@ struct ImBuf *BKE_sequencer_render_mask_input( void BKE_sequencer_color_balance_apply(struct StripColorBalance *cb, struct ImBuf *ibuf, float mul, bool make_float, struct ImBuf *mask_input); void BKE_sequencer_all_free_anim_ibufs(struct Main *bmain, int cfra); +void BKE_sequencer_update_scene_strip_start_end(struct Scene *scene, int orig_sfra, int orig_efra); #endif /* __BKE_SEQUENCER_H__ */ diff --git a/source/blender/blenkernel/intern/sequencer.c b/source/blender/blenkernel/intern/sequencer.c index c02a47db321..33a912d9ec4 100644 --- a/source/blender/blenkernel/intern/sequencer.c +++ b/source/blender/blenkernel/intern/sequencer.c @@ -5726,3 +5726,50 @@ void BKE_sequencer_all_free_anim_ibufs(Main *bmain, int cfra) sequencer_all_free_anim_ibufs(&ed->seqbase, cfra); } } + +/** +* When the start or end frames of a scene are changed, we need to find any sequence strips that +* use this scene and update them to match. +* +* \param scene: pointer to the scene that has been changed. +* \param orig_sfra: the value of sfra before the change was made. +* \param orig_efra: the value of efra before the change was made. +*/ +void BKE_sequencer_update_scene_strip_start_end(Scene *scene, int orig_sfra, int orig_efra) +{ + Sequence *seq; + Scene *parent; + + parent = scene; + /* Wind to end in case we're in the middle of the linked list. */ + while (parent->id.next != NULL) { + parent = (Scene *)parent->id.next; + } + /* Look back through all the other scenes looking for a VSE scene which references this scene. */ + while (parent != NULL) { + if ((parent->ed != NULL) && (parent->ed->seqbasep != NULL)) { + /* Look for this scene's address in the pointers to scenes in each sequence. */ + seq = parent->ed->seqbasep->first; + while (seq != NULL) { + if (seq->scene == scene) { + /* Found it! Recalculate len so that the VSE can show the green bar where there is scene data... */ + seq->len = scene->r.efra - scene->r.sfra + 1; + /* ... but make sure to leave the strip the same length (so adjust end offset / still frames). + * N.B. we do everything in the end offset, because scene strips start at the scene's start + * frame - changing the start frame moves everything left/right, it doesn't adjust the start offset / still. */ + seq->endstill += orig_efra - scene->r.efra; + seq->endstill += scene->r.sfra - orig_sfra; + if (seq->endstill < 0) + { + seq->endofs = 0 - seq->endstill; + seq->endstill = 0; + } + BKE_sequence_invalidate_cache(parent, seq); + /* There may be multiple scene strips using this scene so we should not break here. */ + } + seq = seq->next; + } + } + parent = (Scene *)parent->id.prev; + } +} diff --git a/source/blender/makesrna/intern/rna_scene.c b/source/blender/makesrna/intern/rna_scene.c index 4d499b93ab2..8ca2b10b3ac 100644 --- a/source/blender/makesrna/intern/rna_scene.c +++ b/source/blender/makesrna/intern/rna_scene.c @@ -732,22 +732,30 @@ static void rna_Scene_start_frame_set(PointerRNA *ptr, int value) Scene *data = (Scene *)ptr->data; /* MINFRAME not MINAFRAME, since some output formats can't taken negative frames */ CLAMP(value, MINFRAME, MAXFRAME); + int orig_sfra = data->r.sfra; data->r.sfra = value; if (data->r.sfra >= data->r.efra) { data->r.efra = MIN2(data->r.sfra, MAXFRAME); } + + /* Update any sequence strips using this scene. */ + BKE_sequencer_update_scene_strip_start_end(data, orig_sfra, data->r.efra); } static void rna_Scene_end_frame_set(PointerRNA *ptr, int value) { Scene *data = (Scene *)ptr->data; CLAMP(value, MINFRAME, MAXFRAME); + int orig_efra = data->r.efra; data->r.efra = value; if (data->r.sfra >= data->r.efra) { data->r.sfra = MAX2(data->r.efra, MINFRAME); } + + /* Update any sequence strips using this scene. */ + BKE_sequencer_update_scene_strip_start_end(data, data->r.sfra, orig_efra); } static void rna_Scene_use_preview_range_set(PointerRNA *ptr, bool value)