diff options
author | Campbell Barton <ideasman42@gmail.com> | 2014-12-10 17:26:41 +0300 |
---|---|---|
committer | Campbell Barton <ideasman42@gmail.com> | 2015-11-25 16:15:08 +0300 |
commit | 485ea4353f293317ce395a75663758092cb6f969 (patch) | |
tree | 164dc1aca9839b118b76e846ac428085591a507a /source/blender | |
parent | 456fdaba67e1ab3035ab916fc31b336d452ab99e (diff) |
Sequencer: nested scene strip support (like metas)
This makes it possible to use scenes as a kind of
multi-user meta-strip (with their own time).
Currently this supports rendering & drawing nested strips,
but no convenient way to tab-enter into a scene strip.
Diffstat (limited to 'source/blender')
-rw-r--r-- | source/blender/blenkernel/BKE_sequencer.h | 1 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/sequencer.c | 115 | ||||
-rw-r--r-- | source/blender/editors/space_sequencer/sequencer_draw.c | 31 | ||||
-rw-r--r-- | source/blender/makesdna/DNA_sequence_types.h | 3 | ||||
-rw-r--r-- | source/blender/makesrna/intern/rna_sequencer.c | 7 | ||||
-rw-r--r-- | source/blender/render/intern/source/pipeline.c | 11 |
6 files changed, 136 insertions, 32 deletions
diff --git a/source/blender/blenkernel/BKE_sequencer.h b/source/blender/blenkernel/BKE_sequencer.h index 11f2d0e0816..3f2712e0ae1 100644 --- a/source/blender/blenkernel/BKE_sequencer.h +++ b/source/blender/blenkernel/BKE_sequencer.h @@ -237,6 +237,7 @@ void BKE_sequencer_base_clipboard_pointers_restore(struct ListBase *seqbase, str void BKE_sequence_free(struct Scene *scene, struct Sequence *seq); void BKE_sequence_free_anim(struct Sequence *seq); const char *BKE_sequence_give_name(struct Sequence *seq); +ListBase *BKE_sequence_seqbase_get(struct Sequence *seq, int *r_offset); void BKE_sequence_calc(struct Scene *scene, struct Sequence *seq); void BKE_sequence_calc_disp(struct Scene *scene, struct Sequence *seq); void BKE_sequence_reload_new_file(struct Scene *scene, struct Sequence *seq, const bool lock_range); diff --git a/source/blender/blenkernel/intern/sequencer.c b/source/blender/blenkernel/intern/sequencer.c index a87935ae23b..6e722e7bc63 100644 --- a/source/blender/blenkernel/intern/sequencer.c +++ b/source/blender/blenkernel/intern/sequencer.c @@ -91,6 +91,8 @@ # include AUD_SPECIAL_H #endif +#define USE_SCENE_RECURSIVE_HACK + static ImBuf *seq_render_strip_stack(const SeqRenderData *context, ListBase *seqbasep, float cfra, int chanshown); static ImBuf *seq_render_strip(const SeqRenderData *context, Sequence *seq, float cfra); static void seq_free_animdata(Scene *scene, Sequence *seq); @@ -1149,6 +1151,33 @@ const char *BKE_sequence_give_name(Sequence *seq) return name; } +ListBase *BKE_sequence_seqbase_get(Sequence *seq, int *r_offset) +{ + ListBase *seqbase = NULL; + + switch (seq->type) { + case SEQ_TYPE_META: + { + seqbase = &seq->seqbase; + *r_offset = seq->start; + break; + } + case SEQ_TYPE_SCENE: + { + if (seq->flag & SEQ_SCENE_STRIPS) { + Editing *ed = BKE_sequencer_editing_get(seq->scene, false); + if (ed) { + seqbase = &ed->seqbase; + *r_offset = seq->scene->r.sfra; + } + } + break; + } + } + + return seqbase; +} + /*********************** DO THE SEQUENCE *************************/ static void make_black_ibuf(ImBuf *ibuf) @@ -3319,6 +3348,40 @@ finally: return ibuf; } +/** + * Used for meta-strips & scenes with #SEQ_SCENE_STRIPS flag set. + */ +static ImBuf *do_render_strip_seqbase( + const SeqRenderData *context, Sequence *seq, float nr, + bool use_preprocess) +{ + ImBuf *meta_ibuf = NULL, *ibuf = NULL; + ListBase *seqbase = NULL; + int offset; + + seqbase = BKE_sequence_seqbase_get(seq, &offset); + + if (seqbase && !BLI_listbase_is_empty(seqbase)) { + meta_ibuf = seq_render_strip_stack( + context, seqbase, + /* scene strips don't have their start taken into account */ + nr + offset, 0); + } + + if (meta_ibuf) { + ibuf = meta_ibuf; + if (ibuf && use_preprocess) { + ImBuf *i = IMB_dupImBuf(ibuf); + + IMB_freeImBuf(ibuf); + + ibuf = i; + } + } + + return ibuf; +} + static ImBuf *do_render_strip_uncached(const SeqRenderData *context, Sequence *seq, float cfra) { ImBuf *ibuf = NULL; @@ -3329,22 +3392,38 @@ static ImBuf *do_render_strip_uncached(const SeqRenderData *context, Sequence *s switch (type) { case SEQ_TYPE_META: { - ImBuf *meta_ibuf = NULL; - - if (seq->seqbase.first) - meta_ibuf = seq_render_strip_stack(context, &seq->seqbase, seq->start + nr, 0); + ibuf = do_render_strip_seqbase(context, seq, nr, use_preprocess); + break; + } - if (meta_ibuf) { - ibuf = meta_ibuf; - if (ibuf && use_preprocess) { - ImBuf *i = IMB_dupImBuf(ibuf); + case SEQ_TYPE_SCENE: + { + if (seq->flag & SEQ_SCENE_STRIPS) { + if (seq->scene && (context->scene != seq->scene)) { +#ifdef USE_SCENE_RECURSIVE_HACK + /* weak recusrive check, same as T32017 */ + if (seq->scene->id.flag & LIB_DOIT) { + break; + } + seq->scene->id.flag |= LIB_DOIT; +#endif - IMB_freeImBuf(ibuf); + ibuf = do_render_strip_seqbase(context, seq, nr, use_preprocess); - ibuf = i; +#ifdef USE_SCENE_RECURSIVE_HACK + seq->scene->id.flag &= ~LIB_DOIT; +#endif } } + else { + /* scene can be NULL after deletions */ + ibuf = seq_render_scene_strip(context, seq, nr, cfra); + /* Scene strips update all animation, so we need to restore original state.*/ + BKE_animsys_evaluate_all_animation(context->bmain, context->scene, cfra); + + copy_to_ibuf_still(context, seq, nr, ibuf); + } break; } @@ -3395,18 +3474,6 @@ static ImBuf *do_render_strip_uncached(const SeqRenderData *context, Sequence *s break; } - case SEQ_TYPE_SCENE: - { - /* scene can be NULL after deletions */ - ibuf = seq_render_scene_strip(context, seq, nr, cfra); - - /* Scene strips update all animation, so we need to restore original state.*/ - BKE_animsys_evaluate_all_animation(context->bmain, context->scene, cfra); - - copy_to_ibuf_still(context, seq, nr, ibuf); - break; - } - case SEQ_TYPE_MOVIECLIP: { ibuf = seq_render_movieclip_strip(context, seq, nr); @@ -3731,6 +3798,10 @@ ImBuf *BKE_sequencer_give_ibuf(const SeqRenderData *context, float cfra, int cha seqbasep = ed->seqbasep; } +#ifdef USE_SCENE_RECURSIVE_HACK + BKE_main_id_tag_idcode(context->bmain, ID_SCE, false); +#endif + return seq_render_strip_stack(context, seqbasep, cfra, chanshown); } diff --git a/source/blender/editors/space_sequencer/sequencer_draw.c b/source/blender/editors/space_sequencer/sequencer_draw.c index 2ae7cdd4f98..ebc41878910 100644 --- a/source/blender/editors/space_sequencer/sequencer_draw.c +++ b/source/blender/editors/space_sequencer/sequencer_draw.c @@ -301,6 +301,20 @@ static void drawmeta_contents(Scene *scene, Sequence *seqm, float x1, float y1, int chan_range = 0; float draw_range = y2 - y1; float draw_height; + ListBase *seqbase; + int offset; + + seqbase = BKE_sequence_seqbase_get(seqm, &offset); + if (!seqbase || BLI_listbase_is_empty(seqbase)) { + return; + } + + if (seqm->type == SEQ_TYPE_SCENE) { + offset = seqm->start - offset; + } + else { + offset = 0; + } glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); @@ -308,7 +322,7 @@ static void drawmeta_contents(Scene *scene, Sequence *seqm, float x1, float y1, if (seqm->flag & SEQ_MUTE) drawmeta_stipple(1); - for (seq = seqm->seqbase.first; seq; seq = seq->next) { + for (seq = seqbase->first; seq; seq = seq->next) { chan_min = min_ii(chan_min, seq->machine); chan_max = max_ii(chan_max, seq->machine); } @@ -318,11 +332,14 @@ static void drawmeta_contents(Scene *scene, Sequence *seqm, float x1, float y1, col[3] = 196; /* alpha, used for all meta children */ - for (seq = seqm->seqbase.first; seq; seq = seq->next) { - if ((seq->startdisp > x2 || seq->enddisp < x1) == 0) { + for (seq = seqbase->first; seq; seq = seq->next) { + const int startdisp = seq->startdisp + offset; + const int enddisp = seq->enddisp + offset; + + if ((startdisp > x2 || enddisp < x1) == 0) { float y_chan = (seq->machine - chan_min) / (float)(chan_range) * draw_range; - float x1_chan = seq->startdisp; - float x2_chan = seq->enddisp; + float x1_chan = startdisp; + float x2_chan = enddisp; float y1_chan, y2_chan; if ((seqm->flag & SEQ_MUTE) == 0 && (seq->flag & SEQ_MUTE)) @@ -830,7 +847,9 @@ static void draw_seq_strip(const bContext *C, SpaceSeq *sseq, Scene *scene, AReg glDisable(GL_LINE_STIPPLE); } - if (seq->type == SEQ_TYPE_META) { + if ((seq->type == SEQ_TYPE_META) || + ((seq->type == SEQ_TYPE_SCENE) && (seq->flag & SEQ_SCENE_STRIPS))) + { drawmeta_contents(scene, seq, x1, y1, x2, y2); } diff --git a/source/blender/makesdna/DNA_sequence_types.h b/source/blender/makesdna/DNA_sequence_types.h index 69e7fb43fb6..e5c102b1d2d 100644 --- a/source/blender/makesdna/DNA_sequence_types.h +++ b/source/blender/makesdna/DNA_sequence_types.h @@ -417,6 +417,9 @@ enum { SEQ_SCENE_NO_GPENCIL = (1 << 28), SEQ_USE_VIEWS = (1 << 29), + /* access scene strips directly (like a metastrip) */ + SEQ_SCENE_STRIPS = (1 << 30), + SEQ_INVALID_EFFECT = (1 << 31), }; diff --git a/source/blender/makesrna/intern/rna_sequencer.c b/source/blender/makesrna/intern/rna_sequencer.c index de138699e3a..1fb57fc1d11 100644 --- a/source/blender/makesrna/intern/rna_sequencer.c +++ b/source/blender/makesrna/intern/rna_sequencer.c @@ -1901,7 +1901,12 @@ static void rna_def_scene(BlenderRNA *brna) RNA_def_property_pointer_funcs(prop, NULL, NULL, NULL, "rna_Camera_object_poll"); RNA_def_property_ui_text(prop, "Camera Override", "Override the scenes active camera"); RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, "rna_Sequence_update"); - + + prop = RNA_def_property(srna, "use_sequence", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flag", SEQ_SCENE_STRIPS); + RNA_def_property_ui_text(prop, "Use Sequence", "Use scenes sequence strips directly, instead of rendering"); + RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, "rna_Sequence_update"); + prop = RNA_def_property(srna, "use_grease_pencil", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_negative_sdna(prop, NULL, "flag", SEQ_SCENE_NO_GPENCIL); RNA_def_property_ui_text(prop, "Use Grease Pencil", "Show Grease Pencil strokes in OpenGL previews"); diff --git a/source/blender/render/intern/source/pipeline.c b/source/blender/render/intern/source/pipeline.c index 3ae93649ee2..d565b8a657c 100644 --- a/source/blender/render/intern/source/pipeline.c +++ b/source/blender/render/intern/source/pipeline.c @@ -2832,6 +2832,8 @@ static bool check_valid_camera_multiview(Scene *scene, Object *camera, ReportLis static int check_valid_camera(Scene *scene, Object *camera_override, ReportList *reports) { + const char *err_msg = "No camera found in scene \"%s\""; + if (camera_override == NULL && scene->camera == NULL) scene->camera = BKE_scene_camera_find(scene); @@ -2843,14 +2845,17 @@ static int check_valid_camera(Scene *scene, Object *camera_override, ReportList Sequence *seq = scene->ed->seqbase.first; while (seq) { - if (seq->type == SEQ_TYPE_SCENE && seq->scene) { + if ((seq->type == SEQ_TYPE_SCENE) && + ((seq->flag & SEQ_SCENE_STRIPS) == 0) && + (seq->scene != NULL)) + { if (!seq->scene_camera) { if (!seq->scene->camera && !BKE_scene_camera_find(seq->scene)) { /* camera could be unneeded due to composite nodes */ Object *override = (seq->scene == scene) ? camera_override : NULL; if (!check_valid_compositing_camera(seq->scene, override)) { - BKE_reportf(reports, RPT_ERROR, "No camera found in scene \"%s\"", seq->scene->id.name+2); + BKE_reportf(reports, RPT_ERROR, err_msg, seq->scene->id.name + 2); return false; } } @@ -2864,7 +2869,7 @@ static int check_valid_camera(Scene *scene, Object *camera_override, ReportList } } else if (!check_valid_compositing_camera(scene, camera_override)) { - BKE_report(reports, RPT_ERROR, "No camera found in scene"); + BKE_reportf(reports, RPT_ERROR, err_msg, scene->id.name + 2); return false; } |