Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/source
diff options
context:
space:
mode:
authorCampbell Barton <ideasman42@gmail.com>2012-06-07 22:24:36 +0400
committerCampbell Barton <ideasman42@gmail.com>2012-06-07 22:24:36 +0400
commitbdf9e023466756b6a75722cfa05ce75150e5ad75 (patch)
treeb40653194b5a1b9f2fa8e31720df4b15bd6dc0f6 /source
parent32530c28274c9c0de0707b39a6be9e4bafe7b257 (diff)
new sequence strip type for masks.
Diffstat (limited to 'source')
-rw-r--r--source/blender/blenkernel/BKE_mask.h5
-rw-r--r--source/blender/blenkernel/intern/mask.c80
-rw-r--r--source/blender/blenkernel/intern/sequencer.c96
-rw-r--r--source/blender/blenloader/intern/readfile.c4
-rw-r--r--source/blender/compositor/operations/COM_MaskOperation.cpp2
-rw-r--r--source/blender/editors/include/UI_resources.h1
-rw-r--r--source/blender/editors/interface/resources.c12
-rw-r--r--source/blender/editors/space_sequencer/sequencer_add.c108
-rw-r--r--source/blender/editors/space_sequencer/sequencer_draw.c17
-rw-r--r--source/blender/editors/space_sequencer/sequencer_intern.h1
-rw-r--r--source/blender/editors/space_sequencer/sequencer_ops.c1
-rw-r--r--source/blender/editors/space_sequencer/sequencer_select.c13
-rw-r--r--source/blender/editors/space_sequencer/space_sequencer.c6
-rw-r--r--source/blender/makesdna/DNA_mask_types.h2
-rw-r--r--source/blender/makesdna/DNA_sequence_types.h2
-rw-r--r--source/blender/makesdna/DNA_userdef_types.h4
-rw-r--r--source/blender/makesrna/RNA_access.h1
-rw-r--r--source/blender/makesrna/RNA_enum_types.h3
-rw-r--r--source/blender/makesrna/intern/rna_mask.c40
-rw-r--r--source/blender/makesrna/intern/rna_sequencer.c23
-rw-r--r--source/blender/makesrna/intern/rna_sequencer_api.c38
-rw-r--r--source/blender/nodes/composite/nodes/node_composite_mask.c2
-rw-r--r--source/blender/windowmanager/intern/wm_operators.c10
23 files changed, 428 insertions, 43 deletions
diff --git a/source/blender/blenkernel/BKE_mask.h b/source/blender/blenkernel/BKE_mask.h
index 8a8281dafa0..32f86bd3ebe 100644
--- a/source/blender/blenkernel/BKE_mask.h
+++ b/source/blender/blenkernel/BKE_mask.h
@@ -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)
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 <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;
}
@@ -731,6 +732,15 @@ void reload_sequence_new_file(Scene *scene, Sequence *seq, int lock_range)
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) {
+ seq->len = 0;
+ }
+ break;
case SEQ_TYPE_SOUND_RAM:
#ifdef WITH_AUDASPACE
if (!seq->sound)
@@ -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)
diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c
index cce38ff1d90..85d597ccbdd 100644
--- a/source/blender/blenloader/intern/readfile.c
+++ b/source/blender/blenloader/intern/readfile.c
@@ -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;
diff --git a/source/blender/compositor/operations/COM_MaskOperation.cpp b/source/blender/compositor/operations/COM_MaskOperation.cpp
index a742306f440..a7c1de323f1 100644
--- a/source/blender/compositor/operations/COM_MaskOperation.cpp
+++ b/source/blender/compositor/operations/COM_MaskOperation.cpp
@@ -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;
}
diff --git a/source/blender/editors/include/UI_resources.h b/source/blender/editors/include/UI_resources.h
index 2ef5277a3c6..51df30d6c28 100644
--- a/source/blender/editors/include/UI_resources.h
+++ b/source/blender/editors/include/UI_resources.h
@@ -151,6 +151,7 @@ enum {
TH_SEQ_MOVIE,
TH_SEQ_MOVIECLIP,
+ TH_SEQ_MASK,
TH_SEQ_IMAGE,
TH_SEQ_SCENE,
TH_SEQ_AUDIO,
diff --git a/source/blender/editors/interface/resources.c b/source/blender/editors/interface/resources.c
index 2e70a941a54..02f34873ea7 100644
--- a/source/blender/editors/interface/resources.c
+++ b/source/blender/editors/interface/resources.c
@@ -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;
diff --git a/source/blender/editors/space_sequencer/sequencer_add.c b/source/blender/editors/space_sequencer/sequencer_add.c
index 9301f13c8c0..26bedd14d6e 100644
--- a/source/blender/editors/space_sequencer/sequencer_add.c
+++ b/source/blender/editors/space_sequencer/sequencer_add.c
@@ -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)
{
diff --git a/source/blender/editors/space_sequencer/sequencer_draw.c b/source/blender/editors/space_sequencer/sequencer_draw.c
index cb15eed6a37..eb943451b1f 100644
--- a/source/blender/editors/space_sequencer/sequencer_draw.c
+++ b/source/blender/editors/space_sequencer/sequencer_draw.c
@@ -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);
diff --git a/source/blender/editors/space_sequencer/sequencer_intern.h b/source/blender/editors/space_sequencer/sequencer_intern.h
index 19cd7ed4ad4..25a322c6905 100644
--- a/source/blender/editors/space_sequencer/sequencer_intern.h
+++ b/source/blender/editors/space_sequencer/sequencer_intern.h
@@ -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);
diff --git a/source/blender/editors/space_sequencer/sequencer_ops.c b/source/blender/editors/space_sequencer/sequencer_ops.c
index 3a02c90f99a..79ecd9f7481 100644
--- a/source/blender/editors/space_sequencer/sequencer_ops.c
+++ b/source/blender/editors/space_sequencer/sequencer_ops.c
@@ -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);
diff --git a/source/blender/editors/space_sequencer/sequencer_select.c b/source/blender/editors/space_sequencer/sequencer_select.c
index 261bc575420..b03edfc61b9 100644
--- a/source/blender/editors/space_sequencer/sequencer_select.c
+++ b/source/blender/editors/space_sequencer/sequencer_select.c
@@ -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;
}
diff --git a/source/blender/editors/space_sequencer/space_sequencer.c b/source/blender/editors/space_sequencer/space_sequencer.c
index 4168cb9ac77..cc59a05b781 100644
--- a/source/blender/editors/space_sequencer/space_sequencer.c
+++ b/source/blender/editors/space_sequencer/space_sequencer.c
@@ -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;
}
}
diff --git a/source/blender/makesdna/DNA_mask_types.h b/source/blender/makesdna/DNA_mask_types.h
index 23f33729f69..626242c1a8d 100644
--- a/source/blender/makesdna/DNA_mask_types.h
+++ b/source/blender/makesdna/DNA_mask_types.h
@@ -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 {
diff --git a/source/blender/makesdna/DNA_sequence_types.h b/source/blender/makesdna/DNA_sequence_types.h
index 73b6efedd77..161c448476d 100644
--- a/source/blender/makesdna/DNA_sequence_types.h
+++ b/source/blender/makesdna/DNA_sequence_types.h
@@ -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,
diff --git a/source/blender/makesdna/DNA_userdef_types.h b/source/blender/makesdna/DNA_userdef_types.h
index f06a2b6f80a..5465dbf6e3c 100644
--- a/source/blender/makesdna/DNA_userdef_types.h
+++ b/source/blender/makesdna/DNA_userdef_types.h
@@ -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];
diff --git a/source/blender/makesrna/RNA_access.h b/source/blender/makesrna/RNA_access.h
index c9914a35a14..37455563ee0 100644
--- a/source/blender/makesrna/RNA_access.h
+++ b/source/blender/makesrna/RNA_access.h
@@ -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;
diff --git a/source/blender/makesrna/RNA_enum_types.h b/source/blender/makesrna/RNA_enum_types.h
index d2eeaa72fed..473ab7485b0 100644
--- a/source/blender/makesrna/RNA_enum_types.h
+++ b/source/blender/makesrna/RNA_enum_types.h
@@ -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__ */
diff --git a/source/blender/makesrna/intern/rna_mask.c b/source/blender/makesrna/intern/rna_mask.c
index 51d370d5a88..f25aba6193b 100644
--- a/source/blender/makesrna/intern/rna_mask.c
+++ b/source/blender/makesrna/intern/rna_mask.c
@@ -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);
}
diff --git a/source/blender/makesrna/intern/rna_sequencer.c b/source/blender/makesrna/intern/rna_sequencer.c
index 1edf144452d..fb8ba2f863e 100644
--- a/source/blender/makesrna/intern/rna_sequencer.c
+++ b/source/blender/makesrna/intern/rna_sequencer.c
@@ -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);
diff --git a/source/blender/makesrna/intern/rna_sequencer_api.c b/source/blender/makesrna/intern/rna_sequencer_api.c
index bbc772770ea..e20435a07cd 100644
--- a/source/blender/makesrna/intern/rna_sequencer_api.c
+++ b/source/blender/makesrna/intern/rna_sequencer_api.c
@@ -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");
diff --git a/source/blender/nodes/composite/nodes/node_composite_mask.c b/source/blender/nodes/composite/nodes/node_composite_mask.c
index c90c7918660..01461aec08d 100644
--- a/source/blender/nodes/composite/nodes/node_composite_mask.c
+++ b/source/blender/nodes/composite/nodes/node_composite_mask.c
@@ -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;
diff --git a/source/blender/windowmanager/intern/wm_operators.c b/source/blender/windowmanager/intern/wm_operators.c
index ed023e42ea3..425baac25fd 100644
--- a/source/blender/windowmanager/intern/wm_operators.c
+++ b/source/blender/windowmanager/intern/wm_operators.c
@@ -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);
+}
+