new sequence strip type for masks.

This commit is contained in:
2012-06-07 18:24:36 +00:00
parent 32530c2827
commit bdf9e02346
25 changed files with 484 additions and 46 deletions

View 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'

View 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):

View 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)

View 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 (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;
}
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);

View 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)

View 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;

View 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;
}

View File

@@ -151,6 +151,7 @@ enum {
TH_SEQ_MOVIE,
TH_SEQ_MOVIECLIP,
TH_SEQ_MASK,
TH_SEQ_IMAGE,
TH_SEQ_SCENE,
TH_SEQ_AUDIO,

View 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;

View 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)
{

View 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);

View 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);

View 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);

View 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;
}

View 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;
}
}

View 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 {

View 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,

View 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];

View 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;

View 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__ */

View 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);
}

View 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);

View 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");

View 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;

View 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);
}