new sequence strip type for masks.
authorCampbell Barton <ideasman42@gmail.com>
Thu, 7 Jun 2012 18:24:36 +0000 (18:24 +0000)
committerCampbell Barton <ideasman42@gmail.com>
Thu, 7 Jun 2012 18:24:36 +0000 (18:24 +0000)
25 files changed:
release/scripts/startup/bl_ui/space_clip.py
release/scripts/startup/bl_ui/space_sequencer.py
source/blender/blenkernel/BKE_mask.h
source/blender/blenkernel/intern/mask.c
source/blender/blenkernel/intern/sequencer.c
source/blender/blenloader/intern/readfile.c
source/blender/compositor/operations/COM_MaskOperation.cpp
source/blender/editors/include/UI_resources.h
source/blender/editors/interface/resources.c
source/blender/editors/space_sequencer/sequencer_add.c
source/blender/editors/space_sequencer/sequencer_draw.c
source/blender/editors/space_sequencer/sequencer_intern.h
source/blender/editors/space_sequencer/sequencer_ops.c
source/blender/editors/space_sequencer/sequencer_select.c
source/blender/editors/space_sequencer/space_sequencer.c
source/blender/makesdna/DNA_mask_types.h
source/blender/makesdna/DNA_sequence_types.h
source/blender/makesdna/DNA_userdef_types.h
source/blender/makesrna/RNA_access.h
source/blender/makesrna/RNA_enum_types.h
source/blender/makesrna/intern/rna_mask.c
source/blender/makesrna/intern/rna_sequencer.c
source/blender/makesrna/intern/rna_sequencer_api.c
source/blender/nodes/composite/nodes/node_composite_mask.c
source/blender/windowmanager/intern/wm_operators.c

index 0174762fcc81afbb9f0ea27d39136820b9d307fa..4bec1ad18ba5678d074265106885f44e0dff3e4b 100644 (file)
@@ -790,6 +790,24 @@ class CLIP_PT_display(CLIP_PT_clip_view_panel, Panel):
             col.prop(sc, "show_mask_smooth")
 
 
+# TODO, move into its own file
+class CLIP_PT_mask(CLIP_PT_mask_view_panel, Panel):
+    bl_space_type = 'CLIP_EDITOR'
+    bl_region_type = 'UI'
+    bl_label = "Mask Settings"
+    bl_options = {'DEFAULT_CLOSED'}
+
+    def draw(self, context):
+        layout = self.layout
+
+        sc = context.space_data
+        mask = sc.mask
+
+        col = layout.column(align=True)
+        col.prop(mask, "frame_start")
+        col.prop(mask, "frame_end")
+
+
 class CLIP_PT_marker_display(CLIP_PT_clip_view_panel, Panel):
     bl_space_type = 'CLIP_EDITOR'
     bl_region_type = 'UI'
index 732f675c2086222b0d15910b07c70adc160ca0ea..276e8e5ae1d35f75b8d28ddadb7d8aad9c0af569 100644 (file)
@@ -198,6 +198,12 @@ class SEQUENCER_MT_add(Menu):
         else:
             layout.operator_menu_enum("sequencer.movieclip_strip_add", "clip", text="Clip...")
 
+        if len(bpy.data.masks) > 10:
+            layout.operator_context = 'INVOKE_DEFAULT'
+            layout.operator("sequencer.mask_strip_add", text="Masks...")
+        else:
+            layout.operator_menu_enum("sequencer.mask_strip_add", "mask", text="Mask...")
+
         layout.operator("sequencer.movie_strip_add", text="Movie")
         layout.operator("sequencer.image_strip_add", text="Image")
         layout.operator("sequencer.sound_strip_add", text="Sound")
@@ -670,6 +676,35 @@ class SEQUENCER_PT_scene(SequencerButtonsPanel, Panel):
             layout.label(text="Original frame range" + ": %d-%d (%d)" % (sta, end, end - sta + 1))
 
 
+class SEQUENCER_PT_mask(SequencerButtonsPanel, Panel):
+    bl_label = "Mask"
+
+    @classmethod
+    def poll(cls, context):
+        if not cls.has_sequencer(context):
+            return False
+
+        strip = act_strip(context)
+        if not strip:
+            return False
+
+        return (strip.type == 'MASK')
+
+    def draw(self, context):
+        layout = self.layout
+
+        strip = act_strip(context)
+
+        layout.template_ID(strip, "mask")
+
+        mask = strip.mask
+
+        if mask:
+            sta = mask.frame_start
+            end = mask.frame_end
+            layout.label(text="Original frame range" + ": %d-%d (%d)" % (sta, end, end - sta + 1))
+
+
 class SEQUENCER_PT_filter(SequencerButtonsPanel, Panel):
     bl_label = "Filter"
 
@@ -682,10 +717,10 @@ class SEQUENCER_PT_filter(SequencerButtonsPanel, Panel):
         if not strip:
             return False
 
-        return strip.type in {'MOVIE', 'IMAGE', 'SCENE', 'MOVIECLIP', 'META',
-                              'ADD', 'SUBTRACT', 'ALPHA_OVER', 'ALPHA_UNDER',
-                              'CROSS', 'GAMMA_CROSS', 'MULTIPLY', 'OVER_DROP',
-                              'WIPE', 'GLOW', 'TRANSFORM', 'COLOR',
+        return strip.type in {'MOVIE', 'IMAGE', 'SCENE', 'MOVIECLIP', 'MASK',
+                              'META', 'ADD', 'SUBTRACT', 'ALPHA_OVER',
+                              'ALPHA_UNDER', 'CROSS', 'GAMMA_CROSS', 'MULTIPLY',
+                              'OVER_DROP', 'WIPE', 'GLOW', 'TRANSFORM', 'COLOR',
                               'MULTICAM', 'SPEED', 'ADJUSTMENT'}
 
     def draw(self, context):
index 8a8281dafa0bfb4cf7985f3e35598b9e0e6b299f..32f86bd3ebec6daf527a1f81e2346c257aa14a33 100644 (file)
@@ -120,6 +120,7 @@ void BKE_mask_coord_to_movieclip(struct MovieClip *clip, struct MovieClipUser *u
 void BKE_mask_update_display(struct Mask *mask, float ctime);
 
 void BKE_mask_evaluate_all_masks(struct Main *bmain, float ctime, const int do_newframe);
+void BKE_mask_evaluate(struct Mask *mask, float ctime, const int do_newframe);
 void BKE_mask_update_scene(struct Main *bmain, struct Scene *scene, const int do_newframe);
 void BKE_mask_parent_init(struct MaskParent *parent);
 void BKE_mask_calc_handle_adjacent_interp(struct MaskSpline *spline, struct MaskSplinePoint *point, const float u);
@@ -165,7 +166,9 @@ void BKE_mask_layer_shape_changed_add(struct MaskLayer *masklay, int index,
 void BKE_mask_layer_shape_changed_remove(struct MaskLayer *masklay, int index, int count);
 
 /* rasterization */
-void BKE_mask_rasterize(struct Mask *mask, int width, int height, float *buffer);
+int BKE_mask_get_duration(struct Mask *mask);
+void BKE_mask_rasterize(struct Mask *mask, int width, int height, float *buffer,
+                        const short do_aspect_correct, const short do_linear);
 
 #define MASKPOINT_ISSEL_ANY(p)          ( ((p)->bezt.f1 | (p)->bezt.f2 | (p)->bezt.f2) & SELECT)
 #define MASKPOINT_ISSEL_KNOT(p)         ( (p)->bezt.f2 & SELECT)
index aaae58a6ab78be2b894231509af657ba8a605b38..b942b633aeff84793d5192c2193ed3641bc26594 100644 (file)
@@ -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);
index 699e0b1cd97f8fe346f35d8591229a96a3cf17a8..97733404b091df6d004f44b12feeaae4fce8f4fd 100644 (file)
@@ -29,7 +29,6 @@
  *  \ingroup bke
  */
 
-
 #include <stddef.h>
 #include <stdlib.h>
 #include <string.h>
@@ -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)
index cce38ff1d90b7fc61fdbb989be4e8141763a117f..85d597ccbdd6fe7b0ea37182e102b634eb449c5c 100644 (file)
@@ -4828,6 +4828,10 @@ static void lib_link_scene(FileData *fd, Main *main)
                                        seq->clip = newlibadr(fd, sce->id.lib, seq->clip);
                                        seq->clip->id.us++;
                                }
+                               if (seq->mask) {
+                                       seq->mask = newlibadr(fd, sce->id.lib, seq->mask);
+                                       seq->mask->id.us++;
+                               }
                                if (seq->scene_camera) seq->scene_camera = newlibadr(fd, sce->id.lib, seq->scene_camera);
                                if (seq->sound) {
                                        seq->scene_sound = NULL;
index a742306f4401bafd84d78accd97f4b1e1c65d304..a7c1de323f1d4f7463f27483696046376d575ae4 100644 (file)
@@ -75,7 +75,7 @@ void *MaskOperation::initializeTileData(rcti *rect, MemoryBuffer **memoryBuffers
                float *buffer;
 
                buffer = (float *)MEM_callocN(sizeof(float) * width * height, "rasterized mask");
-               BKE_mask_rasterize(mask, width, height, buffer);
+               BKE_mask_rasterize(mask, width, height, buffer, TRUE, TRUE);
 
                this->rasterizedMask = buffer;
        }
index 2ef5277a3c667f7e0f4adb0971b45b175d468d39..51df30d6c285b120fb324f3308d2eef70b05a6cf 100644 (file)
@@ -151,6 +151,7 @@ enum {
        
        TH_SEQ_MOVIE,
        TH_SEQ_MOVIECLIP,
+       TH_SEQ_MASK,
        TH_SEQ_IMAGE,
        TH_SEQ_SCENE,
        TH_SEQ_AUDIO,
index 2e70a941a54331f459e00c6332e618edfbfe2412..02f34873ea77fd82338f6d06c298f0dfebe505fd 100644 (file)
@@ -372,6 +372,8 @@ const unsigned char *UI_ThemeGetColorPtr(bTheme *btheme, int spacetype, int colo
                                        cp = ts->movie; break;
                                case TH_SEQ_MOVIECLIP:
                                        cp = ts->movieclip; break;
+                               case TH_SEQ_MASK:
+                                       cp = ts->mask; break;
                                case TH_SEQ_IMAGE:
                                        cp = ts->image; break;
                                case TH_SEQ_SCENE:
@@ -819,6 +821,7 @@ void ui_theme_init_default(void)
        rgba_char_args_set(btheme->tseq.back,   116, 116, 116, 255);
        rgba_char_args_set(btheme->tseq.movie,  81, 105, 135, 255);
        rgba_char_args_set(btheme->tseq.movieclip,  32, 32, 143, 255);
+       rgba_char_args_set(btheme->tseq.mask,   152, 78, 62, 255);
        rgba_char_args_set(btheme->tseq.image,  109, 88, 129, 255);
        rgba_char_args_set(btheme->tseq.scene,  78, 152, 62, 255);
        rgba_char_args_set(btheme->tseq.audio,  46, 143, 143, 255);
@@ -1899,6 +1902,15 @@ void init_userdef_do_versions(void)
                }
        }
 
+       if (bmain->versionfile < 263 || (bmain->versionfile == 263 && bmain->subversionfile < 11)) {
+               bTheme *btheme;
+               for (btheme = U.themes.first; btheme; btheme = btheme->next) {
+                       if (btheme->tseq.movieclip[0] == 0) {
+                               rgba_char_args_set(btheme->tseq.mask,  152, 78, 62, 255);
+                       }
+               }
+       }
+
        /* GL Texture Garbage Collection (variable abused above!) */
        if (U.textimeout == 0) {
                U.texcollectrate = 60;
index 9301f13c8c0e6612a6c9661a04ba492d8974805a..26bedd14d6e268feebb2f5693b50eda0b944c0be 100644 (file)
@@ -46,6 +46,7 @@
 #include "BLI_utildefines.h"
 
 #include "DNA_scene_types.h"
+#include "DNA_mask_types.h"
 #include "DNA_userdef_types.h"
 
 #include "BKE_context.h"
@@ -54,6 +55,8 @@
 #include "BKE_main.h"
 #include "BKE_sequencer.h"
 #include "BKE_movieclip.h"
+#include "BKE_sequencer.h"
+#include "BKE_mask.h"
 #include "BKE_report.h"
 
 #include "WM_api.h"
@@ -360,7 +363,6 @@ static int sequencer_add_movieclip_strip_exec(bContext *C, wmOperator *op)
        return OPERATOR_FINISHED;
 }
 
-
 static int sequencer_add_movieclip_strip_invoke(bContext *C, wmOperator *op, wmEvent *event)
 {
        if (!ED_operator_sequencer_active(C)) {
@@ -377,11 +379,10 @@ static int sequencer_add_movieclip_strip_invoke(bContext *C, wmOperator *op, wmE
        // return WM_menu_invoke(C, op, event);
 }
 
-
 void SEQUENCER_OT_movieclip_strip_add(struct wmOperatorType *ot)
 {
        PropertyRNA *prop;
-       
+
        /* identifiers */
        ot->name = "Add MovieClip Strip";
        ot->idname = "SEQUENCER_OT_movieclip_strip_add";
@@ -392,16 +393,113 @@ void SEQUENCER_OT_movieclip_strip_add(struct wmOperatorType *ot)
        ot->exec = sequencer_add_movieclip_strip_exec;
 
        ot->poll = ED_operator_scene_editable;
-       
+
        /* flags */
        ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
-       
+
        sequencer_generic_props__internal(ot, SEQPROP_STARTFRAME);
        prop = RNA_def_enum(ot->srna, "clip", DummyRNA_NULL_items, 0, "Clip", "");
        RNA_def_enum_funcs(prop, RNA_movieclip_itemf);
        ot->prop = prop;
 }
 
+static int sequencer_add_mask_strip_exec(bContext *C, wmOperator *op)
+{
+       Scene *scene = CTX_data_scene(C);
+       Editing *ed = BKE_sequencer_editing_get(scene, TRUE);
+
+       Mask *mask;
+
+       Sequence *seq;  /* generic strip vars */
+       Strip *strip;
+
+       int start_frame, channel; /* operator props */
+
+       start_frame = RNA_int_get(op->ptr, "frame_start");
+       channel = RNA_int_get(op->ptr, "channel");
+
+       mask = BLI_findlink(&CTX_data_main(C)->mask, RNA_enum_get(op->ptr, "mask"));
+
+       if (mask == NULL) {
+               BKE_report(op->reports, RPT_ERROR, "Mask not found");
+               return OPERATOR_CANCELLED;
+       }
+
+       seq = alloc_sequence(ed->seqbasep, start_frame, channel);
+       seq->type = SEQ_TYPE_MASK;
+       seq->blend_mode = SEQ_TYPE_CROSS;
+       seq->mask = mask;
+
+       if (seq->mask->id.us == 0)
+               seq->mask->id.us = 1;
+
+       /* basic defaults */
+       seq->strip = strip = MEM_callocN(sizeof(Strip), "strip");
+       seq->len = BKE_mask_get_duration(mask);
+       strip->us = 1;
+
+       BLI_strncpy(seq->name + 2, mask->id.name + 2, sizeof(seq->name) - 2);
+       seqbase_unique_name_recursive(&ed->seqbase, seq);
+
+       calc_sequence_disp(scene, seq);
+       BKE_sequencer_sort(scene);
+
+       if (RNA_boolean_get(op->ptr, "replace_sel")) {
+               ED_sequencer_deselect_all(scene);
+               BKE_sequencer_active_set(scene, seq);
+               seq->flag |= SELECT;
+       }
+
+       if (RNA_boolean_get(op->ptr, "overlap") == FALSE) {
+               if (seq_test_overlap(ed->seqbasep, seq)) shuffle_seq(ed->seqbasep, seq, scene);
+       }
+
+       WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene);
+
+       return OPERATOR_FINISHED;
+}
+
+static int sequencer_add_mask_strip_invoke(bContext *C, wmOperator *op, wmEvent *event)
+{
+       if (!ED_operator_sequencer_active(C)) {
+               BKE_report(op->reports, RPT_ERROR, "Sequencer area not active");
+               return OPERATOR_CANCELLED;
+       }
+
+       if (!RNA_struct_property_is_set(op->ptr, "mask"))
+               return WM_enum_search_invoke(C, op, event);
+
+       sequencer_generic_invoke_xy__internal(C, op, event, 0);
+       return sequencer_add_mask_strip_exec(C, op);
+       // needs a menu
+       // return WM_menu_invoke(C, op, event);
+}
+
+
+void SEQUENCER_OT_mask_strip_add(struct wmOperatorType *ot)
+{
+       PropertyRNA *prop;
+
+       /* identifiers */
+       ot->name = "Add Mask Strip";
+       ot->idname = "SEQUENCER_OT_mask_strip_add";
+       ot->description = "Add a mask strip to the sequencer";
+
+       /* api callbacks */
+       ot->invoke = sequencer_add_mask_strip_invoke;
+       ot->exec = sequencer_add_mask_strip_exec;
+
+       ot->poll = ED_operator_scene_editable;
+
+       /* flags */
+       ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+
+       sequencer_generic_props__internal(ot, SEQPROP_STARTFRAME);
+       prop = RNA_def_enum(ot->srna, "mask", DummyRNA_NULL_items, 0, "Mask", "");
+       RNA_def_enum_funcs(prop, RNA_mask_itemf);
+       ot->prop = prop;
+}
+
 
 static int sequencer_add_generic_strip_exec(bContext *C, wmOperator *op, SeqLoadFunc seq_load_func)
 {
index cb15eed6a37c58a35e2101202189b15aeec39538..eb943451b1fc4acf0c32bac2bd82fc67b3f21dcb 100644 (file)
@@ -40,6 +40,7 @@
 #include "IMB_imbuf_types.h"
 
 #include "DNA_scene_types.h"
+#include "DNA_mask_types.h"
 #include "DNA_screen_types.h"
 #include "DNA_space_types.h"
 #include "DNA_userdef_types.h"
@@ -97,7 +98,11 @@ static void get_seq_color3ubv(Scene *curscene, Sequence *seq, unsigned char col[
                case SEQ_TYPE_MOVIECLIP:
                        UI_GetThemeColor3ubv(TH_SEQ_MOVIECLIP, col);
                        break;
-               
+
+               case SEQ_TYPE_MASK:
+                       UI_GetThemeColor3ubv(TH_SEQ_MASK, col); /* TODO */
+                       break;
+
                case SEQ_TYPE_SCENE:
                        UI_GetThemeColor3ubv(TH_SEQ_SCENE, col);
                
@@ -550,6 +555,16 @@ static void draw_seq_text(View2D *v2d, Sequence *seq, float x1, float x2, float
                                     seq->len, name);
                }
        }
+       else if (seq->type == SEQ_TYPE_MASK) {
+               if (seq->mask && strcmp(name, seq->mask->id.name + 2) != 0) {
+                       BLI_snprintf(str, sizeof(str), "%d | %s: %s",
+                                    seq->len, name, seq->mask->id.name + 2);
+               }
+               else {
+                       BLI_snprintf(str, sizeof(str), "%d | %s",
+                                    seq->len, name);
+               }
+       }
        else if (seq->type == SEQ_TYPE_MULTICAM) {
                BLI_snprintf(str, sizeof(str), "Cam | %s: %d",
                             name, seq->multicam_source);
index 19cd7ed4ad43f75c2953bc546608a45fecef9e0f..25a322c69051406cb9c96441adb0cfeb66d7b8d8 100644 (file)
@@ -138,6 +138,7 @@ void SEQUENCER_OT_select_grouped(struct wmOperatorType *ot);
 void SEQUENCER_OT_scene_strip_add(struct wmOperatorType *ot);
 void SEQUENCER_OT_movie_strip_add(struct wmOperatorType *ot);
 void SEQUENCER_OT_movieclip_strip_add(struct wmOperatorType *ot);
+void SEQUENCER_OT_mask_strip_add(struct wmOperatorType *ot);
 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);
index 3a02c90f99a217cff1b70788d1083da366dfb4e2..79ecd9f7481078a8a2d45439b974373ec08d60d5 100644 (file)
@@ -105,6 +105,7 @@ void sequencer_operatortypes(void)
        /* sequencer_add.c */
        WM_operatortype_append(SEQUENCER_OT_scene_strip_add);
        WM_operatortype_append(SEQUENCER_OT_movieclip_strip_add);
+       WM_operatortype_append(SEQUENCER_OT_mask_strip_add);
        WM_operatortype_append(SEQUENCER_OT_movie_strip_add);
        WM_operatortype_append(SEQUENCER_OT_sound_strip_add);
        WM_operatortype_append(SEQUENCER_OT_image_strip_add);
index 261bc57542013bd0342d23b9f9e1d15773144575..b03edfc61b906bc5434d4c986a2c163e932c1024 100644 (file)
@@ -934,7 +934,7 @@ static EnumPropertyItem sequencer_prop_select_grouped_types[] = {
 
 #define SEQ_IS_EFFECT(_seq) (_seq->type & SEQ_TYPE_EFFECT)
 
-#define SEQ_USE_DATA(_seq) (ELEM(_seq->type, SEQ_TYPE_SCENE, SEQ_TYPE_MOVIECLIP) || SEQ_HAS_PATH(_seq))
+#define SEQ_USE_DATA(_seq) (ELEM3(_seq->type, SEQ_TYPE_SCENE, SEQ_TYPE_MOVIECLIP, SEQ_TYPE_MASK) || SEQ_HAS_PATH(_seq))
 
 static short select_grouped_type(Editing *ed, Sequence *actseq)
 {
@@ -1030,6 +1030,17 @@ static short select_grouped_data(Editing *ed, Sequence *actseq)
                }
                SEQ_END;
        }
+       else if (actseq->type == SEQ_TYPE_MASK) {
+               struct Mask *mask = actseq->mask;
+               SEQP_BEGIN (ed, seq)
+               {
+                       if (seq->type == SEQ_TYPE_MASK && seq->mask == mask) {
+                               seq->flag |= SELECT;
+                               changed = TRUE;
+                       }
+               }
+               SEQ_END;
+       }
 
        return changed;
 }
index 4168cb9ac77afdee56be586945e58a82c2b979cf..cc59a05b781b64258bcc2291c49c9bcd3c8869e1 100644 (file)
@@ -482,6 +482,12 @@ static void sequencer_preview_area_listener(ARegion *ar, wmNotifier *wmn)
                                        break;
                        }
                        break;
+
+               case NC_MASK:
+                       if (wmn->action == NA_EDITED) {
+                               ED_region_tag_redraw(ar);
+                       }
+                       break;
        }
 }
 
index 23f33729f69e9ca6ebf010fdf5db252e4cd68fc1..626242c1a8d8ce3891d767ec95e7929b8da36de8 100644 (file)
@@ -46,6 +46,8 @@ typedef struct Mask {
        ListBase masklayers;  /* mask layers */
        int masklay_act;      /* index of active mask layer (-1 == None) */
        int masklay_tot;      /* total number of mask layers */
+
+       int sfra, efra;       /* frames, used by the sequencer */
 } Mask;
 
 typedef struct MaskParent {
index 73b6efedd770ab34e976100fccf9230002d63918..161c448476d176e25019932676e0438196a25885 100644 (file)
@@ -132,6 +132,7 @@ typedef struct Sequence {
 
        struct anim *anim;      /* for MOVIE strips */
        struct MovieClip *clip; /* for MOVIECLIP strips */
+       struct Mask *mask;      /* for MASK strips */
 
        float effect_fader;
        float speed_fader;
@@ -305,6 +306,7 @@ enum {
        SEQ_TYPE_SOUND_RAM   = 4,
        SEQ_TYPE_SOUND_HD    = 5,
        SEQ_TYPE_MOVIECLIP   = 6,
+       SEQ_TYPE_MASK        = 7,
 
        SEQ_TYPE_EFFECT      = 8,
        SEQ_TYPE_CROSS       = 8,
index f06a2b6f80adf79c9dabd2a655f06cd93501f261..5465dbf6e3c259953af54e4079d7f5671fd4c3ff 100644 (file)
@@ -236,7 +236,7 @@ typedef struct ThemeSpace {
        char syntaxl[4], syntaxn[4], syntaxb[4]; // syntax for textwindow and nodes
        char syntaxv[4], syntaxc[4];
        
-       char movie[4], movieclip[4], image[4], scene[4], audio[4];              // for sequence editor
+       char movie[4], movieclip[4], mask[4], image[4], scene[4], audio[4];             // for sequence editor
        char effect[4], hpad0[4], transition[4], meta[4];
        char editmesh_active[4]; 
 
@@ -249,7 +249,7 @@ typedef struct ThemeSpace {
        char bundle_solid[4];
        char path_before[4], path_after[4];
        char camera_path[4];
-       char hpad[7];
+       char hpad[3];
        
        char preview_back[4];
        char preview_stitch_face[4];
index c9914a35a1431a05e06a352465b4e525e85a1f03..37455563ee02ae21d44a260144ebb35cc19ffbfd 100644 (file)
@@ -295,6 +295,7 @@ extern StructRNA RNA_Macro;
 extern StructRNA RNA_MagicTexture;
 extern StructRNA RNA_MarbleTexture;
 extern StructRNA RNA_MaskModifier;
+extern StructRNA RNA_MaskSequence;
 extern StructRNA RNA_Material;
 extern StructRNA RNA_MaterialHalo;
 extern StructRNA RNA_MaterialPhysics;
index d2eeaa72fed50fbd3f98bc304940b32dce3a3998..473ab7485b09f5ff866af6411e7e475e5ccca643 100644 (file)
@@ -144,6 +144,7 @@ EnumPropertyItem *RNA_scene_itemf(struct bContext *C, struct PointerRNA *ptr, st
 EnumPropertyItem *RNA_scene_local_itemf(struct bContext *C, struct PointerRNA *ptr, struct PropertyRNA *prop, int *free);
 EnumPropertyItem *RNA_movieclip_itemf(struct bContext *C, struct PointerRNA *ptr, struct PropertyRNA *prop, int *free);
 EnumPropertyItem *RNA_movieclip_local_itemf(struct bContext *C, struct PointerRNA *ptr, struct PropertyRNA *prop, int *free);
-
+EnumPropertyItem *RNA_mask_itemf(struct bContext *C, struct PointerRNA *ptr, struct PropertyRNA *prop, int *free);
+EnumPropertyItem *RNA_mask_local_itemf(struct bContext *C, struct PointerRNA *ptr, struct PropertyRNA *prop, int *free);
 
 #endif /* __RNA_ENUM_TYPES_H__ */
index 51d370d5a886548a75427cc08bc4884149751efd..f25aba6193bd37ea12643e5af7b182b0ae6eeaf8 100644 (file)
@@ -312,6 +312,29 @@ static void rna_MaskLayer_spline_add(ID *id, MaskLayer *masklay, int number)
        WM_main_add_notifier(NC_MASK|NA_EDITED, mask);
 }
 
+static void rna_Mask_start_frame_set(PointerRNA *ptr, int value)
+{
+       Mask *data = (Mask *)ptr->data;
+       /* MINFRAME not MINAFRAME, since some output formats can't taken negative frames */
+       CLAMP(value, MINFRAME, MAXFRAME);
+       data->sfra = value;
+
+       if (data->sfra >= data->efra) {
+               data->efra = MIN2(data->sfra, MAXFRAME);
+       }
+}
+
+static void rna_Mask_end_frame_set(PointerRNA *ptr, int value)
+{
+       Mask *data = (Mask *)ptr->data;
+       CLAMP(value, MINFRAME, MAXFRAME);
+       data->efra = value;
+
+       if (data->sfra >= data->efra) {
+               data->sfra = MAX2(data->efra, MINFRAME);
+       }
+}
+
 #else
 
 static void rna_def_maskParent(BlenderRNA *brna)
@@ -644,6 +667,23 @@ static void rna_def_mask(BlenderRNA *brna)
        RNA_def_property_int_funcs(prop, "rna_Mask_layer_active_index_get", "rna_Mask_layer_active_index_set", "rna_Mask_layer_active_index_range");
        RNA_def_property_ui_text(prop, "Active Shape Index", "Index of active layer in list of all mask's layers");
 
+       /* frame range */
+       prop = RNA_def_property(srna, "frame_start", PROP_INT, PROP_TIME);
+       RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
+       RNA_def_property_int_sdna(prop, NULL, "sfra");
+       RNA_def_property_int_funcs(prop, NULL, "rna_Mask_start_frame_set", NULL);
+       RNA_def_property_range(prop, MINFRAME, MAXFRAME);
+       RNA_def_property_ui_text(prop, "Start Frame", "First frame of the mask (used for sequencer)");
+       RNA_def_property_update(prop, NC_SCENE | ND_FRAME_RANGE, NULL);
+
+       prop = RNA_def_property(srna, "frame_end", PROP_INT, PROP_TIME);
+       RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
+       RNA_def_property_int_sdna(prop, NULL, "efra");
+       RNA_def_property_int_funcs(prop, NULL, "rna_Mask_end_frame_set", NULL);
+       RNA_def_property_range(prop, MINFRAME, MAXFRAME);
+       RNA_def_property_ui_text(prop, "End Frame", "Final frame of the mask (used for sequencer)");
+       RNA_def_property_update(prop, NC_SCENE | ND_FRAME_RANGE, NULL);
+
        /* pointers */
        rna_def_animdata_common(srna);
 }
index 1edf144452d8ea4f873b69bca6b2e445703347d4..fb8ba2f863e080e10efaa7f7a5c116becf430a6c 100644 (file)
@@ -406,6 +406,8 @@ static StructRNA *rna_Sequence_refine(struct PointerRNA *ptr)
                        return &RNA_MovieSequence;
                case SEQ_TYPE_MOVIECLIP:
                        return &RNA_MovieClipSequence;
+               case SEQ_TYPE_MASK:
+                       return &RNA_MaskSequence;
                case SEQ_TYPE_SOUND_RAM:
                        return &RNA_SoundSequence;
                case SEQ_TYPE_CROSS:
@@ -989,6 +991,7 @@ static void rna_def_sequence(BlenderRNA *brna)
                {SEQ_TYPE_SCENE, "SCENE", 0, "Scene", ""},
                {SEQ_TYPE_MOVIE, "MOVIE", 0, "Movie", ""},
                {SEQ_TYPE_MOVIECLIP, "MOVIECLIP", 0, "Clip", ""},
+               {SEQ_TYPE_MASK, "MASK", 0, "Mask", ""},
                {SEQ_TYPE_SOUND_RAM, "SOUND", 0, "Sound", ""},
                {SEQ_TYPE_CROSS, "CROSS", 0, "Cross", ""},
                {SEQ_TYPE_ADD, "ADD", 0, "Add", ""},
@@ -1505,6 +1508,8 @@ static void rna_def_movieclip(BlenderRNA *brna)
        RNA_def_struct_ui_text(srna, "MovieClip Sequence", "Sequence strip to load a video from the clip editor");
        RNA_def_struct_sdna(srna, "Sequence");
 
+       /* TODO - add clip property? */
+
        prop = RNA_def_property(srna, "undistort", PROP_BOOLEAN, PROP_NONE);
        RNA_def_property_boolean_sdna(prop, NULL, "clip_flag", SEQ_MOVIECLIP_RENDER_UNDISTORTED);
        RNA_def_property_ui_text(prop, "Undistort Clip", "Use the undistorted version of the clip");
@@ -1519,6 +1524,23 @@ static void rna_def_movieclip(BlenderRNA *brna)
        rna_def_input(srna);
 }
 
+static void rna_def_mask(BlenderRNA *brna)
+{
+       StructRNA *srna;
+       PropertyRNA *prop;
+
+       srna = RNA_def_struct(brna, "MaskSequence", "Sequence");
+       RNA_def_struct_ui_text(srna, "Mask Sequence", "Sequence strip to load a video from a mask");
+       RNA_def_struct_sdna(srna, "Sequence");
+
+       prop = RNA_def_property(srna, "mask", PROP_POINTER, PROP_NONE);
+       RNA_def_property_flag(prop, PROP_EDITABLE);
+       RNA_def_property_ui_text(prop, "Mask", "Mask that this sequence uses");
+       RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, "rna_Sequence_update");
+
+       rna_def_filter_video(srna);
+       rna_def_input(srna);
+}
 
 static void rna_def_sound(BlenderRNA *brna)
 {
@@ -1883,6 +1905,7 @@ void RNA_def_sequencer(BlenderRNA *brna)
        rna_def_scene(brna);
        rna_def_movie(brna);
        rna_def_movieclip(brna);
+       rna_def_mask(brna);
        rna_def_sound(brna);
        rna_def_effect(brna);
        rna_def_effects(brna);
index bbc772770ea9aa4a8d7f1c9a9591e85fa3bfbcaf..e20435a07cd7b17baa8a8d21218cc8ad49a7c7d5 100644 (file)
@@ -45,6 +45,7 @@ extern EnumPropertyItem blend_mode_items[];
 #include "DNA_image_types.h"
 #include "DNA_scene_types.h"
 #include "DNA_sequence_types.h"
+#include "DNA_mask_types.h"
 #include "DNA_sound_types.h"
 
 #include "BLI_path_util.h" /* BLI_split_dirfile */
@@ -52,6 +53,7 @@ extern EnumPropertyItem blend_mode_items[];
 #include "BKE_image.h"
 #include "BKE_library.h" /* id_us_plus */
 #include "BKE_movieclip.h"
+#include "BKE_mask.h"
 
 #include "BKE_report.h"
 #include "BKE_sequencer.h"
@@ -116,6 +118,25 @@ static Sequence *rna_Sequences_new_clip(ID *id, Editing *ed, ReportList *reports
        return seq;
 }
 
+static Sequence *rna_Sequences_new_mask(ID *id, Editing *ed, ReportList *reports,
+                                        const char *name, Mask *mask, int channel,
+                                        int start_frame)
+{
+       Scene *scene = (Scene *)id;
+       Sequence *seq;
+
+       seq = alloc_generic_sequence(ed, name, start_frame, channel, SEQ_TYPE_MASK, mask->id.name);
+       seq->mask = mask;
+       seq->len = BKE_mask_get_duration(mask);
+       id_us_plus((ID *)mask);
+
+       calc_sequence_disp(scene, seq);
+
+       WM_main_add_notifier(NC_SCENE | ND_SEQUENCER, scene);
+
+       return seq;
+}
+
 static Sequence *rna_Sequences_new_scene(ID *id, Editing *ed, ReportList *reports,
                                          const char *name, Scene *sce_seq, int channel,
                                          int start_frame)
@@ -451,6 +472,23 @@ void RNA_api_sequences(BlenderRNA *brna, PropertyRNA *cprop)
        parm = RNA_def_pointer(func, "sequence", "Sequence", "", "New Sequence");
        RNA_def_function_return(func, parm);
 
+       func = RNA_def_function(srna, "new_mask", "rna_Sequences_new_mask");
+       RNA_def_function_flag(func, FUNC_USE_REPORTS | FUNC_USE_SELF_ID);
+       RNA_def_function_ui_description(func, "Add a new movie clip sequence");
+       parm = RNA_def_string(func, "name", "Name", 0, "", "New name for the sequence");
+       RNA_def_property_flag(parm, PROP_REQUIRED);
+       parm = RNA_def_pointer(func, "mask", "Mask", "", "Mask to add");
+       RNA_def_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL);
+       parm = RNA_def_int(func, "channel", 0, 0, MAXSEQ - 1, "Channel",
+                          "The channel for the new sequence", 0, MAXSEQ - 1);
+       RNA_def_property_flag(parm, PROP_REQUIRED);
+       parm = RNA_def_int(func, "start_frame", 0, -MAXFRAME, MAXFRAME, "",
+                          "The start frame for the new sequence", -MAXFRAME, MAXFRAME);
+       RNA_def_property_flag(parm, PROP_REQUIRED);
+       /* return type */
+       parm = RNA_def_pointer(func, "sequence", "Sequence", "", "New Sequence");
+       RNA_def_function_return(func, parm);
+
        func = RNA_def_function(srna, "new_scene", "rna_Sequences_new_scene");
        RNA_def_function_flag(func, FUNC_USE_REPORTS | FUNC_USE_SELF_ID);
        RNA_def_function_ui_description(func, "Add a new scene sequence");
index c90c7918660102d51f15377c89e9466ac99d868d..01461aec08d832444d8fed3fe51145d5fe61a8e1 100644 (file)
@@ -81,7 +81,7 @@ static void exec(void *data, bNode *node, bNodeStack **in, bNodeStack **out)
                stackbuf = alloc_compbuf(sx, sy, CB_VAL, TRUE);
                res = stackbuf->rect;
 
-               BKE_mask_rasterize(mask, sx, sy, res);
+               BKE_mask_rasterize(mask, sx, sy, res, TRUE, TRUE);
 
                /* pass on output and free */
                out[0]->data = stackbuf;
index ed023e42ea3fc0cbb9f64fc871c896fcaf73724b..425baac25fd7a020190f2784f0dfb37e05ed903c 100644 (file)
@@ -4166,3 +4166,13 @@ EnumPropertyItem *RNA_movieclip_local_itemf(bContext *C, PointerRNA *ptr, Proper
 {
        return rna_id_itemf(C, ptr, do_free, C ? (ID *)CTX_data_main(C)->movieclip.first : NULL, TRUE);
 }
+
+EnumPropertyItem *RNA_mask_itemf(bContext *C, PointerRNA *ptr, PropertyRNA *UNUSED(prop), int *do_free)
+{
+       return rna_id_itemf(C, ptr, do_free, C ? (ID *)CTX_data_main(C)->mask.first : NULL, FALSE);
+}
+EnumPropertyItem *RNA_mask_local_itemf(bContext *C, PointerRNA *ptr, PropertyRNA *UNUSED(prop), int *do_free)
+{
+       return rna_id_itemf(C, ptr, do_free, C ? (ID *)CTX_data_main(C)->mask.first : NULL, TRUE);
+}
+