From bdf9e023466756b6a75722cfa05ce75150e5ad75 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 7 Jun 2012 18:24:36 +0000 Subject: new sequence strip type for masks. --- source/blender/blenkernel/intern/mask.c | 80 +++++++++++++++-------- source/blender/blenkernel/intern/sequencer.c | 96 ++++++++++++++++++++++++++-- 2 files changed, 146 insertions(+), 30 deletions(-) (limited to 'source/blender/blenkernel/intern') diff --git a/source/blender/blenkernel/intern/mask.c b/source/blender/blenkernel/intern/mask.c index aaae58a6ab7..b942b633aef 100644 --- a/source/blender/blenkernel/intern/mask.c +++ b/source/blender/blenkernel/intern/mask.c @@ -951,6 +951,10 @@ Mask *BKE_mask_new(const char *name) mask = mask_alloc(mask_name); + /* arbitrary defaults */ + mask->sfra = 1; + mask->efra = 100; + return mask; } @@ -2040,7 +2044,7 @@ static void m_invert_vn_vn(float *array, const float f, const int size) } } -static void linear_clamp_vn_vn(float *array, const int size) +static void clamp_vn_vn_linear(float *array, const int size) { float *arr = array + (size - 1); @@ -2053,8 +2057,26 @@ static void linear_clamp_vn_vn(float *array, const int size) } } +static void clamp_vn_vn(float *array, const int size) +{ + float *arr = array + (size - 1); + + int i = size; + while (i--) { + if (*arr < 0.0f) *arr = 0.0f; + else if (*arr > 1.0f) *arr = 1.0f; + arr--; + } +} + +int BKE_mask_get_duration(Mask *mask) +{ + return MAX2(1, mask->efra - mask->sfra); +} + /* rasterization */ -void BKE_mask_rasterize(Mask *mask, int width, int height, float *buffer) +void BKE_mask_rasterize(Mask *mask, int width, int height, float *buffer, + const short do_aspect_correct, const short do_linear) { MaskLayer *masklay; @@ -2087,31 +2109,32 @@ void BKE_mask_rasterize(Mask *mask, int width, int height, float *buffer) BKE_mask_spline_feather_differentiated_points_with_resolution(spline, width, height, &tot_diff_feather_points); - /* TODO, make this optional! */ - if (width != height) { - float *fp; - float *ffp; - int i; - float asp; - - if (width < height) { - fp = &diff_points[0][0]; - ffp = tot_diff_feather_points ? &diff_feather_points[0][0] : NULL; - asp = (float)width / (float)height; - } - else { - fp = &diff_points[0][1]; - ffp = tot_diff_feather_points ? &diff_feather_points[0][1] : NULL; - asp = (float)height / (float)width; - } + if (do_aspect_correct) { + if (width != height) { + float *fp; + float *ffp; + int i; + float asp; + + if (width < height) { + fp = &diff_points[0][0]; + ffp = tot_diff_feather_points ? &diff_feather_points[0][0] : NULL; + asp = (float)width / (float)height; + } + else { + fp = &diff_points[0][1]; + ffp = tot_diff_feather_points ? &diff_feather_points[0][1] : NULL; + asp = (float)height / (float)width; + } - for (i = 0; i < tot_diff_point; i++, fp += 2) { - (*fp) = (((*fp) - 0.5f) / asp) + 0.5f; - } + for (i = 0; i < tot_diff_point; i++, fp += 2) { + (*fp) = (((*fp) - 0.5f) / asp) + 0.5f; + } - if (tot_diff_feather_points) { - for (i = 0; i < tot_diff_feather_points; i++, ffp += 2) { - (*ffp) = (((*ffp) - 0.5f) / asp) + 0.5f; + if (tot_diff_feather_points) { + for (i = 0; i < tot_diff_feather_points; i++, ffp += 2) { + (*ffp) = (((*ffp) - 0.5f) / asp) + 0.5f; + } } } } @@ -2173,7 +2196,12 @@ void BKE_mask_rasterize(Mask *mask, int width, int height, float *buffer) } /* clamp at the end */ - linear_clamp_vn_vn(buffer, buffer_size); + if (do_linear) { + clamp_vn_vn_linear(buffer, buffer_size); + } + else { + clamp_vn_vn(buffer, buffer_size); + } } MEM_freeN(buffer_tmp); diff --git a/source/blender/blenkernel/intern/sequencer.c b/source/blender/blenkernel/intern/sequencer.c index 699e0b1cd97..97733404b09 100644 --- a/source/blender/blenkernel/intern/sequencer.c +++ b/source/blender/blenkernel/intern/sequencer.c @@ -29,7 +29,6 @@ * \ingroup bke */ - #include #include #include @@ -40,6 +39,7 @@ #include "DNA_sequence_types.h" #include "DNA_movieclip_types.h" +#include "DNA_mask_types.h" #include "DNA_scene_types.h" #include "DNA_anim_types.h" #include "DNA_object_types.h" @@ -61,6 +61,7 @@ #include "BKE_movieclip.h" #include "BKE_fcurve.h" #include "BKE_scene.h" +#include "BKE_mask.h" #include "BKE_utildefines.h" #include "RNA_access.h" @@ -669,9 +670,9 @@ void reload_sequence_new_file(Scene *scene, Sequence *seq, int lock_range) int prev_startdisp = 0, prev_enddisp = 0; /* note: don't rename the strip, will break animation curves */ - if (ELEM6(seq->type, + if (ELEM7(seq->type, SEQ_TYPE_MOVIE, SEQ_TYPE_IMAGE, SEQ_TYPE_SOUND_RAM, - SEQ_TYPE_SCENE, SEQ_TYPE_META, SEQ_TYPE_MOVIECLIP) == 0) + SEQ_TYPE_SCENE, SEQ_TYPE_META, SEQ_TYPE_MOVIECLIP, SEQ_TYPE_MASK) == 0) { return; } @@ -725,6 +726,15 @@ void reload_sequence_new_file(Scene *scene, Sequence *seq, int lock_range) case SEQ_TYPE_MOVIECLIP: seq->len = BKE_movieclip_get_duration(seq->clip); + seq->len -= seq->anim_startofs; + seq->len -= seq->anim_endofs; + if (seq->len < 0) { + seq->len = 0; + } + break; + case SEQ_TYPE_MASK: + seq->len = BKE_mask_get_duration(seq->mask); + seq->len -= seq->anim_startofs; seq->len -= seq->anim_endofs; if (seq->len < 0) { @@ -903,7 +913,8 @@ static const char *give_seqname_by_type(int type) case SEQ_TYPE_SCENE: return "Scene"; case SEQ_TYPE_MOVIE: return "Movie"; case SEQ_TYPE_MOVIECLIP: return "Clip"; - case SEQ_TYPE_SOUND_RAM: return "Audio"; + case SEQ_TYPE_MASK: return "Mask"; + case SEQ_TYPE_SOUND_RAM: return "Audio"; case SEQ_TYPE_CROSS: return "Cross"; case SEQ_TYPE_GAMCROSS: return "Gamma Cross"; case SEQ_TYPE_ADD: return "Add"; @@ -2044,6 +2055,75 @@ static ImBuf *seq_render_movieclip_strip( return ibuf; } + +static ImBuf *seq_render_mask_strip( + SeqRenderData context, Sequence *seq, float nr) +{ + /* TODO - add option to rasterize to alpha imbuf? */ + ImBuf *ibuf = NULL; + float *maskbuf; + int i; + + if (!seq->mask) { + return NULL; + } + + BKE_mask_evaluate(seq->mask, (int)(seq->mask->sfra + nr), TRUE); + + maskbuf = MEM_callocN(sizeof(float) * context.rectx * context.recty, __func__); + + if (seq->flag & SEQ_MAKE_FLOAT) { + /* pixels */ + float *fp_src; + float *fp_dst; + + ibuf = IMB_allocImBuf(context.rectx, context.recty, 32, IB_rectfloat); + + BKE_mask_rasterize(seq->mask, + context.rectx, context.recty, + maskbuf, + TRUE, FALSE); + + fp_src = maskbuf; + fp_dst = ibuf->rect_float; + i = context.rectx * context.recty; + while(--i) { + fp_dst[0] = fp_dst[1] = fp_dst[2] = *fp_src; + fp_dst[3] = 1.0f; + + fp_src += 1; + fp_dst += 4; + } + } + else { + /* pixels */ + float *fp_src; + unsigned char *ub_dst; + + ibuf = IMB_allocImBuf(context.rectx, context.recty, 32, IB_rect); + + BKE_mask_rasterize(seq->mask, + context.rectx, context.recty, + maskbuf, + TRUE, FALSE); + + fp_src = maskbuf; + ub_dst = (unsigned char *)ibuf->rect; + i = context.rectx * context.recty; + while(--i) { + ub_dst[0] = ub_dst[1] = ub_dst[2] = (unsigned char)(*fp_src * 255.0f); /* already clamped */ + ub_dst[3] = 255; + + fp_src += 1; + ub_dst += 4; + } + } + + MEM_freeN(maskbuf); + + return ibuf; +} + static ImBuf *seq_render_scene_strip( SeqRenderData context, Sequence *seq, float nr) { @@ -2359,6 +2439,14 @@ static ImBuf *seq_render_strip(SeqRenderData context, Sequence *seq, float cfra) copy_to_ibuf_still(context, seq, nr, ibuf); break; } + case SEQ_TYPE_MASK: + { + /* ibuf is alwats new */ + ibuf = seq_render_mask_strip(context, seq, nr); + + copy_to_ibuf_still(context, seq, nr, ibuf); + break; + } } if (ibuf == NULL) -- cgit v1.2.3