shapekeys for masks - this doesnt use existing shapekey code however.
This commit is contained in:
@@ -31,6 +31,7 @@ struct Main;
|
||||
struct Mask;
|
||||
struct MaskParent;
|
||||
struct MaskObject;
|
||||
struct MaskObjectShape;
|
||||
struct MaskSpline;
|
||||
struct MaskSplinePoint;
|
||||
struct MaskSplinePointUW;
|
||||
@@ -83,8 +84,8 @@ void BKE_mask_coord_to_movieclip(struct MovieClip *clip, struct MovieClipUser *u
|
||||
|
||||
/* parenting */
|
||||
|
||||
void BKE_mask_evaluate_all_masks(struct Main *bmain, float ctime);
|
||||
void BKE_mask_update_scene(struct Main *bmain, struct Scene *scene);
|
||||
void BKE_mask_evaluate_all_masks(struct Main *bmain, 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_length(struct Mask *mask, struct MaskSpline *spline, struct MaskSplinePoint *point);
|
||||
void BKE_mask_calc_handle_point(struct Mask *mask, struct MaskSpline *spline, struct MaskSplinePoint *point);
|
||||
@@ -93,6 +94,22 @@ void BKE_mask_get_handle_point_adjacent(struct Mask *mask, struct MaskSpline *sp
|
||||
struct MaskSplinePoint **r_point_prev, struct MaskSplinePoint **r_point_next);
|
||||
void BKE_mask_calc_handles(struct Mask *mask);
|
||||
|
||||
/* animation */
|
||||
int BKE_mask_object_shape_totvert(struct MaskObject *maskobj);
|
||||
void BKE_mask_object_shape_from_mask(struct MaskObject *maskobj, struct MaskObjectShape *maskobj_shape);
|
||||
void BKE_mask_object_shape_to_mask(struct MaskObject *maskobj, struct MaskObjectShape *maskobj_shape);
|
||||
void BKE_mask_object_shape_to_mask_interp(struct MaskObject *maskobj,
|
||||
struct MaskObjectShape *maskobj_shape_a,
|
||||
struct MaskObjectShape *maskobj_shape_b,
|
||||
const float fac);
|
||||
struct MaskObjectShape *BKE_mask_object_shape_find_frame(struct MaskObject *maskobj, int frame);
|
||||
int BKE_mask_object_shape_find_frame_range(struct MaskObject *maskobj, int frame,
|
||||
struct MaskObjectShape **r_maskobj_shape_a,
|
||||
struct MaskObjectShape **r_maskobj_shape_b);
|
||||
struct MaskObjectShape *BKE_mask_object_shape_varify_frame(struct MaskObject *maskobj, int frame);
|
||||
void BKE_mask_object_shape_unlink(struct MaskObject *maskobj, struct MaskObjectShape *maskobj_shape);
|
||||
void BKE_mask_object_shape_sort(struct MaskObject *maskobj);
|
||||
|
||||
#define MASKPOINT_ISSEL(p) ( ((p)->bezt.f1 | (p)->bezt.f2 | (p)->bezt.f2) & SELECT)
|
||||
#define MASKPOINT_SEL(p) { (p)->bezt.f1 |= SELECT; (p)->bezt.f2 |= SELECT; (p)->bezt.f3 |= SELECT; } (void)0
|
||||
#define MASKPOINT_DESEL(p) { (p)->bezt.f1 &= ~SELECT; (p)->bezt.f2 &= ~SELECT; (p)->bezt.f3 &= ~SELECT; } (void)0
|
||||
|
||||
@@ -662,10 +662,20 @@ void BKE_mask_spline_free(MaskSpline *spline)
|
||||
MEM_freeN(spline);
|
||||
}
|
||||
|
||||
void BKE_mask_object_shape_free(MaskObjectShape *maskobj_shape)
|
||||
{
|
||||
MEM_freeN(maskobj_shape->data);
|
||||
|
||||
MEM_freeN(maskobj_shape);
|
||||
}
|
||||
|
||||
void BKE_mask_object_free(MaskObject *maskobj)
|
||||
{
|
||||
MaskSpline *spline = maskobj->splines.first;
|
||||
MaskSpline *spline;
|
||||
MaskObjectShape *maskobj_shape;
|
||||
|
||||
/* free splines */
|
||||
spline = maskobj->splines.first;
|
||||
while (spline) {
|
||||
MaskSpline *next_spline = spline->next;
|
||||
|
||||
@@ -675,6 +685,17 @@ void BKE_mask_object_free(MaskObject *maskobj)
|
||||
spline = next_spline;
|
||||
}
|
||||
|
||||
/* free animation data */
|
||||
maskobj_shape = maskobj->splines_shapes.first;
|
||||
while (maskobj_shape) {
|
||||
MaskObjectShape *next_maskobj_shape = maskobj_shape->next;
|
||||
|
||||
BLI_remlink(&maskobj->splines_shapes, maskobj_shape);
|
||||
BKE_mask_object_shape_free(maskobj_shape);
|
||||
|
||||
maskobj_shape = next_maskobj_shape;
|
||||
}
|
||||
|
||||
MEM_freeN(maskobj);
|
||||
}
|
||||
|
||||
@@ -956,7 +977,7 @@ void BKE_mask_calc_handles(Mask *mask)
|
||||
}
|
||||
}
|
||||
|
||||
void BKE_mask_evaluate(Mask *mask, float ctime)
|
||||
void BKE_mask_evaluate(Mask *mask, float ctime, const int do_newframe)
|
||||
{
|
||||
MaskObject *maskobj;
|
||||
|
||||
@@ -964,6 +985,40 @@ void BKE_mask_evaluate(Mask *mask, float ctime)
|
||||
MaskSpline *spline;
|
||||
int i;
|
||||
|
||||
/* animation if available */
|
||||
if (do_newframe) {
|
||||
MaskObjectShape *maskobj_shape_a;
|
||||
MaskObjectShape *maskobj_shape_b;
|
||||
int found;
|
||||
|
||||
if ((found = BKE_mask_object_shape_find_frame_range(maskobj, (int)ctime,
|
||||
&maskobj_shape_a, &maskobj_shape_b)))
|
||||
{
|
||||
if (found == 1) {
|
||||
#if 0
|
||||
printf("%s: exact %d %d (%d)\n", __func__, (int)ctime, BLI_countlist(&maskobj->splines_shapes),
|
||||
maskobj_shape_a->frame);
|
||||
#endif
|
||||
|
||||
BKE_mask_object_shape_to_mask(maskobj, maskobj_shape_a);
|
||||
}
|
||||
else if (found == 2) {
|
||||
float w = maskobj_shape_b->frame - maskobj_shape_a->frame;
|
||||
#if 0
|
||||
printf("%s: tween %d %d (%d %d)\n", __func__, (int)ctime, BLI_countlist(&maskobj->splines_shapes),
|
||||
maskobj_shape_a->frame, maskobj_shape_b->frame);
|
||||
#endif
|
||||
BKE_mask_object_shape_to_mask_interp(maskobj, maskobj_shape_a, maskobj_shape_b,
|
||||
(ctime - maskobj_shape_a->frame) / w);
|
||||
}
|
||||
else {
|
||||
/* always fail, should never happen */
|
||||
BLI_assert(found == 2);
|
||||
}
|
||||
}
|
||||
}
|
||||
/* animation done... */
|
||||
|
||||
for (spline = maskobj->splines.first; spline; spline = spline->next) {
|
||||
for (i = 0; i < spline->tot_point; i++) {
|
||||
MaskSplinePoint *point = &spline->points[i];
|
||||
@@ -984,22 +1039,22 @@ void BKE_mask_evaluate(Mask *mask, float ctime)
|
||||
BKE_mask_calc_handles(mask);
|
||||
}
|
||||
|
||||
void BKE_mask_evaluate_all_masks(Main *bmain, float ctime)
|
||||
void BKE_mask_evaluate_all_masks(Main *bmain, float ctime, const int do_newframe)
|
||||
{
|
||||
Mask *mask;
|
||||
|
||||
for (mask = bmain->mask.first; mask; mask = mask->id.next) {
|
||||
BKE_mask_evaluate(mask, ctime);
|
||||
BKE_mask_evaluate(mask, ctime, do_newframe);
|
||||
}
|
||||
}
|
||||
|
||||
void BKE_mask_update_scene(Main *bmain, Scene *scene)
|
||||
void BKE_mask_update_scene(Main *bmain, Scene *scene, const int do_newframe)
|
||||
{
|
||||
Mask *mask;
|
||||
|
||||
for (mask = bmain->mask.first; mask; mask = mask->id.next) {
|
||||
if (mask->id.flag & LIB_ID_RECALC) {
|
||||
BKE_mask_evaluate_all_masks(bmain, CFRA);
|
||||
BKE_mask_evaluate_all_masks(bmain, CFRA, do_newframe);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1008,3 +1063,211 @@ void BKE_mask_parent_init(MaskParent *parent)
|
||||
{
|
||||
parent->id_type = ID_MC;
|
||||
}
|
||||
|
||||
|
||||
/* *** own animation/shapekey implimentation ***
|
||||
* BKE_mask_object_shape_XXX */
|
||||
|
||||
int BKE_mask_object_shape_totvert(MaskObject *maskobj)
|
||||
{
|
||||
int tot = 0;
|
||||
MaskSpline *spline;
|
||||
|
||||
for (spline = maskobj->splines.first; spline; spline = spline->next) {
|
||||
tot += spline->tot_point;
|
||||
}
|
||||
|
||||
return tot;
|
||||
}
|
||||
|
||||
/* these functions match. copy is swapped */
|
||||
void BKE_mask_object_shape_from_mask(MaskObject *maskobj, MaskObjectShape *maskobj_shape)
|
||||
{
|
||||
int tot = BKE_mask_object_shape_totvert(maskobj);
|
||||
|
||||
if (maskobj_shape->tot_vert == tot) {
|
||||
float *fp = maskobj_shape->data;
|
||||
|
||||
MaskSpline *spline;
|
||||
for (spline = maskobj->splines.first; spline; spline = spline->next) {
|
||||
int i;
|
||||
for (i = 0; i < spline->tot_point; i++) {
|
||||
BezTriple *bezt = &spline->points[i].bezt;
|
||||
/* *** BKE_mask_object_shape_to_mask - swapped *** */
|
||||
copy_v2_v2(fp, bezt->vec[0]); fp += 2;
|
||||
copy_v2_v2(fp, bezt->vec[1]); fp += 2;
|
||||
copy_v2_v2(fp, bezt->vec[2]); fp += 2;
|
||||
fp[0] = bezt->weight;
|
||||
fp[1] = bezt->radius; fp += 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
printf("%s: vert mismatch %d != %d\n", __func__, maskobj_shape->tot_vert, tot);
|
||||
}
|
||||
}
|
||||
|
||||
void BKE_mask_object_shape_to_mask(MaskObject *maskobj, MaskObjectShape *maskobj_shape)
|
||||
{
|
||||
int tot = BKE_mask_object_shape_totvert(maskobj);
|
||||
|
||||
if (maskobj_shape->tot_vert == tot) {
|
||||
float *fp = maskobj_shape->data;
|
||||
|
||||
MaskSpline *spline;
|
||||
for (spline = maskobj->splines.first; spline; spline = spline->next) {
|
||||
int i;
|
||||
for (i = 0; i < spline->tot_point; i++) {
|
||||
BezTriple *bezt = &spline->points[i].bezt;
|
||||
/* *** BKE_mask_object_shape_from_mask - swapped *** */
|
||||
copy_v2_v2(bezt->vec[0], fp); fp += 2;
|
||||
copy_v2_v2(bezt->vec[1], fp); fp += 2;
|
||||
copy_v2_v2(bezt->vec[2], fp); fp += 2;
|
||||
bezt->weight = fp[0];
|
||||
bezt->radius = fp[1]; fp += 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
printf("%s: vert mismatch %d != %d\n", __func__, maskobj_shape->tot_vert, tot);
|
||||
}
|
||||
}
|
||||
|
||||
BLI_INLINE void interp_v2_v2v2_flfl(float target[2], const float a[2], const float b[2],
|
||||
const float t, const float s)
|
||||
{
|
||||
target[0] = s * a[0] + t * b[0];
|
||||
target[1] = s * a[1] + t * b[1];
|
||||
}
|
||||
|
||||
/* linear interpolation only */
|
||||
void BKE_mask_object_shape_to_mask_interp(MaskObject *maskobj,
|
||||
MaskObjectShape *maskobj_shape_a,
|
||||
MaskObjectShape *maskobj_shape_b,
|
||||
const float fac)
|
||||
{
|
||||
int tot = BKE_mask_object_shape_totvert(maskobj);
|
||||
printf("%.6f\n", fac);
|
||||
if (maskobj_shape_a->tot_vert == tot && maskobj_shape_b->tot_vert == tot) {
|
||||
float *fp_a = maskobj_shape_a->data;
|
||||
float *fp_b = maskobj_shape_b->data;
|
||||
const float ifac = 1.0f - fac;
|
||||
|
||||
MaskSpline *spline;
|
||||
for (spline = maskobj->splines.first; spline; spline = spline->next) {
|
||||
int i;
|
||||
for (i = 0; i < spline->tot_point; i++) {
|
||||
BezTriple *bezt = &spline->points[i].bezt;
|
||||
/* *** BKE_mask_object_shape_from_mask - swapped *** */
|
||||
interp_v2_v2v2_flfl(bezt->vec[0], fp_a, fp_b, fac, ifac); fp_a += 2; fp_b += 2;
|
||||
interp_v2_v2v2_flfl(bezt->vec[1], fp_a, fp_b, fac, ifac); fp_a += 2; fp_b += 2;
|
||||
interp_v2_v2v2_flfl(bezt->vec[2], fp_a, fp_b, fac, ifac); fp_a += 2; fp_b += 2;
|
||||
bezt->weight = (fp_a[0] * ifac) + (fp_b[0] * fac);
|
||||
bezt->radius = (fp_a[1] * ifac) + (fp_b[1] * fac); fp_a += 2; fp_b += 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
printf("%s: vert mismatch %d != %d != %d\n",
|
||||
__func__, maskobj_shape_a->tot_vert, maskobj_shape_b->tot_vert, tot);
|
||||
}
|
||||
}
|
||||
|
||||
MaskObjectShape *BKE_mask_object_shape_find_frame(MaskObject *maskobj, int frame)
|
||||
{
|
||||
MaskObjectShape *maskobj_shape;
|
||||
|
||||
for (maskobj_shape = maskobj->splines_shapes.first;
|
||||
maskobj_shape;
|
||||
maskobj_shape = maskobj_shape->next)
|
||||
{
|
||||
if (frame == maskobj_shape->frame) {
|
||||
return maskobj_shape;
|
||||
}
|
||||
else if (frame > maskobj_shape->frame) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* when returning 2 - the frame isnt found but before/after frames are */
|
||||
int BKE_mask_object_shape_find_frame_range(MaskObject *maskobj, int frame,
|
||||
MaskObjectShape **r_maskobj_shape_a,
|
||||
MaskObjectShape **r_maskobj_shape_b)
|
||||
{
|
||||
MaskObjectShape *maskobj_shape;
|
||||
|
||||
for (maskobj_shape = maskobj->splines_shapes.first;
|
||||
maskobj_shape;
|
||||
maskobj_shape = maskobj_shape->next)
|
||||
{
|
||||
if (frame == maskobj_shape->frame) {
|
||||
*r_maskobj_shape_a = maskobj_shape;
|
||||
*r_maskobj_shape_b = NULL;
|
||||
return 1;
|
||||
}
|
||||
else if (frame < maskobj_shape->frame) {
|
||||
if (maskobj_shape->prev) {
|
||||
*r_maskobj_shape_a = maskobj_shape->prev;
|
||||
*r_maskobj_shape_b = maskobj_shape;
|
||||
return 2;
|
||||
}
|
||||
else {
|
||||
*r_maskobj_shape_a = maskobj_shape;
|
||||
*r_maskobj_shape_b = NULL;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
*r_maskobj_shape_a = NULL;
|
||||
*r_maskobj_shape_b = NULL;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
MaskObjectShape *BKE_mask_object_shape_varify_frame(MaskObject *maskobj, int frame)
|
||||
{
|
||||
MaskObjectShape *maskobj_shape;
|
||||
|
||||
maskobj_shape = BKE_mask_object_shape_find_frame(maskobj, frame);
|
||||
|
||||
if (maskobj_shape == NULL) {
|
||||
int tot_vert = BKE_mask_object_shape_totvert(maskobj);
|
||||
|
||||
maskobj_shape = MEM_mallocN(sizeof(MaskObjectShape), __func__);
|
||||
maskobj_shape->frame = frame;
|
||||
maskobj_shape->tot_vert = tot_vert;
|
||||
maskobj_shape->data = MEM_mallocN(tot_vert * sizeof(float) * MASK_OBJECT_SHAPE_ELEM_SIZE, __func__);
|
||||
|
||||
BLI_addtail(&maskobj->splines_shapes, maskobj_shape);
|
||||
|
||||
BKE_mask_object_shape_sort(maskobj);
|
||||
}
|
||||
|
||||
return maskobj_shape;
|
||||
}
|
||||
|
||||
void BKE_mask_object_shape_unlink(MaskObject *maskobj, MaskObjectShape *maskobj_shape)
|
||||
{
|
||||
BLI_remlink(&maskobj->splines_shapes, maskobj_shape);
|
||||
|
||||
BKE_mask_object_shape_free(maskobj_shape);
|
||||
}
|
||||
|
||||
static int mask_object_shape_sort_cb(void *maskobj_shape_a_ptr, void *maskobj_shape_b_ptr)
|
||||
{
|
||||
MaskObjectShape *maskobj_shape_a = (MaskObjectShape *)maskobj_shape_a_ptr;
|
||||
MaskObjectShape *maskobj_shape_b = (MaskObjectShape *)maskobj_shape_b_ptr;
|
||||
|
||||
if (maskobj_shape_a->frame < maskobj_shape_b->frame) return -1;
|
||||
else if (maskobj_shape_a->frame > maskobj_shape_b->frame) return 1;
|
||||
else return 0;
|
||||
}
|
||||
|
||||
void BKE_mask_object_shape_sort(MaskObject *maskobj)
|
||||
{
|
||||
BLI_sortlist(&maskobj->splines_shapes, mask_object_shape_sort_cb);
|
||||
}
|
||||
|
||||
@@ -1004,7 +1004,7 @@ static void scene_update_tagged_recursive(Main *bmain, Scene *scene, Scene *scen
|
||||
sound_update_scene(scene);
|
||||
|
||||
/* update masking curves */
|
||||
BKE_mask_update_scene(bmain, scene);
|
||||
BKE_mask_update_scene(bmain, scene, FALSE);
|
||||
}
|
||||
|
||||
/* this is called in main loop, doing tagged updates before redraw */
|
||||
@@ -1075,7 +1075,7 @@ void BKE_scene_update_for_newframe(Main *bmain, Scene *sce, unsigned int lay)
|
||||
* so don't call within 'scene_update_tagged_recursive' */
|
||||
DAG_scene_update_flags(bmain, sce, lay, TRUE); // only stuff that moves or needs display still
|
||||
|
||||
BKE_mask_evaluate_all_masks(bmain, ctime);
|
||||
BKE_mask_evaluate_all_masks(bmain, ctime, TRUE);
|
||||
|
||||
/* All 'standard' (i.e. without any dependencies) animation is handled here,
|
||||
* with an 'local' to 'macro' order of evaluation. This should ensure that
|
||||
|
||||
@@ -6197,11 +6197,11 @@ static void direct_link_mask(FileData *fd, Mask *mask)
|
||||
|
||||
for (maskobj = mask->maskobjs.first; maskobj; maskobj = maskobj->next) {
|
||||
MaskSpline *spline;
|
||||
MaskObjectShape *maskobj_shape;
|
||||
|
||||
link_list(fd, &maskobj->splines);
|
||||
|
||||
spline = maskobj->splines.first;
|
||||
while (spline) {
|
||||
for (spline = maskobj->splines.first; spline; spline = spline->next) {
|
||||
int i;
|
||||
|
||||
spline->points = newdataadr(fd, spline->points);
|
||||
@@ -6212,8 +6212,12 @@ static void direct_link_mask(FileData *fd, Mask *mask)
|
||||
if (point->tot_uw)
|
||||
point->uw = newdataadr(fd, point->uw);
|
||||
}
|
||||
}
|
||||
|
||||
spline = spline->next;
|
||||
link_list(fd, &maskobj->splines_shapes);
|
||||
|
||||
for (maskobj_shape = maskobj->splines_shapes.first; maskobj_shape; maskobj_shape = maskobj_shape->next) {
|
||||
maskobj_shape->data = newdataadr(fd, maskobj_shape->data);
|
||||
}
|
||||
|
||||
maskobj->act_spline = newdataadr(fd, maskobj->act_spline);
|
||||
|
||||
@@ -2771,6 +2771,7 @@ static void write_masks(WriteData *wd, ListBase *idbase)
|
||||
|
||||
for (maskobj = mask->maskobjs.first; maskobj; maskobj = maskobj->next) {
|
||||
MaskSpline *spline;
|
||||
MaskObjectShape *maskobj_shape;
|
||||
|
||||
writestruct(wd, DATA, "MaskObject", 1, maskobj);
|
||||
|
||||
@@ -2787,6 +2788,11 @@ static void write_masks(WriteData *wd, ListBase *idbase)
|
||||
writestruct(wd, DATA, "MaskSplinePointUW", point->tot_uw, point->uw);
|
||||
}
|
||||
}
|
||||
|
||||
for (maskobj_shape = maskobj->splines_shapes.first; maskobj_shape; maskobj_shape = maskobj_shape->next) {
|
||||
writestruct(wd, DATA, "MaskObjectShape", 1, maskobj_shape);
|
||||
writedata(wd, DATA, maskobj_shape->tot_vert * sizeof(float) * MASK_OBJECT_SHAPE_ELEM_SIZE, maskobj_shape->data);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -42,6 +42,7 @@ set(SRC
|
||||
mask_ops.c
|
||||
mask_relationships.c
|
||||
mask_select.c
|
||||
mask_shapekey.c
|
||||
|
||||
mask_intern.h
|
||||
)
|
||||
|
||||
@@ -167,6 +167,10 @@ void ED_operatortypes_mask(void)
|
||||
/* relationships */
|
||||
WM_operatortype_append(MASK_OT_parent_set);
|
||||
WM_operatortype_append(MASK_OT_parent_clear);
|
||||
|
||||
/* shapekeys */
|
||||
WM_operatortype_append(MASK_OT_shape_key_insert);
|
||||
WM_operatortype_append(MASK_OT_shape_key_clear);
|
||||
}
|
||||
|
||||
void ED_keymap_mask(wmKeyConfig *keyconf)
|
||||
@@ -210,6 +214,10 @@ void ED_keymap_mask(wmKeyConfig *keyconf)
|
||||
WM_keymap_add_item(keymap, "MASK_OT_parent_set", PKEY, KM_PRESS, KM_CTRL, 0);
|
||||
WM_keymap_add_item(keymap, "MASK_OT_parent_clear", PKEY, KM_PRESS, KM_ALT, 0);
|
||||
|
||||
WM_keymap_add_item(keymap, "MASK_OT_shape_key_insert", IKEY, KM_PRESS, 0, 0);
|
||||
WM_keymap_add_item(keymap, "MASK_OT_shape_key_clear", IKEY, KM_PRESS, KM_ALT, 0);
|
||||
|
||||
|
||||
transform_keymap_for_space(keyconf, keymap, SPACE_CLIP);
|
||||
}
|
||||
|
||||
|
||||
@@ -88,4 +88,8 @@ void ED_mask_aspect(struct bContext *C, float *aspx, float *aspy);
|
||||
void ED_mask_pixelspace_factor(struct bContext *C, float *scalex, float *scaley);
|
||||
void ED_mask_mouse_pos(struct bContext *C, struct wmEvent *event, float co[2]);
|
||||
|
||||
/* mask_shapekey.c */
|
||||
void MASK_OT_shape_key_insert(struct wmOperatorType *ot);
|
||||
void MASK_OT_shape_key_clear(struct wmOperatorType *ot);
|
||||
|
||||
#endif /* __MASK_INTERN_H__ */
|
||||
|
||||
130
source/blender/editors/mask/mask_shapekey.c
Executable file
130
source/blender/editors/mask/mask_shapekey.c
Executable file
@@ -0,0 +1,130 @@
|
||||
/*
|
||||
* ***** BEGIN GPL LICENSE BLOCK *****
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* The Original Code is Copyright (C) 2012 Blender Foundation.
|
||||
* All rights reserved.
|
||||
*
|
||||
*
|
||||
* Contributor(s): Blender Foundation,
|
||||
* Campbell Barton
|
||||
*
|
||||
* ***** END GPL LICENSE BLOCK *****
|
||||
*/
|
||||
|
||||
/** \file blender/editors/mask/mask_shapekey.c
|
||||
* \ingroup edmask
|
||||
*/
|
||||
|
||||
#include "MEM_guardedalloc.h"
|
||||
|
||||
#include "BLI_utildefines.h"
|
||||
#include "BLI_listbase.h"
|
||||
#include "BLI_math.h"
|
||||
|
||||
#include "BKE_context.h"
|
||||
#include "BKE_curve.h"
|
||||
#include "BKE_depsgraph.h"
|
||||
#include "BKE_mask.h"
|
||||
|
||||
#include "DNA_mask_types.h"
|
||||
#include "DNA_scene_types.h"
|
||||
#include "DNA_object_types.h" /* SELECT */
|
||||
|
||||
#include "WM_api.h"
|
||||
#include "WM_types.h"
|
||||
|
||||
#include "ED_screen.h"
|
||||
#include "ED_mask.h"
|
||||
#include "ED_clip.h"
|
||||
|
||||
#include "RNA_access.h"
|
||||
#include "RNA_define.h"
|
||||
|
||||
#include "mask_intern.h" /* own include */
|
||||
|
||||
static int mask_shape_key_insert_exec(bContext *C, wmOperator *UNUSED(op))
|
||||
{
|
||||
Scene *scene = CTX_data_scene(C);
|
||||
const int frame = CFRA;
|
||||
Mask *mask = CTX_data_edit_mask(C);
|
||||
MaskObject *maskobj;
|
||||
|
||||
for (maskobj = mask->maskobjs.first; maskobj; maskobj = maskobj->next) {
|
||||
MaskObjectShape *maskobj_shape;
|
||||
|
||||
maskobj_shape = BKE_mask_object_shape_varify_frame(maskobj, frame);
|
||||
BKE_mask_object_shape_from_mask(maskobj, maskobj_shape);
|
||||
}
|
||||
|
||||
WM_event_add_notifier(C, NC_MASK | ND_DATA, mask);
|
||||
DAG_id_tag_update(&mask->id, 0);
|
||||
|
||||
return OPERATOR_FINISHED;
|
||||
}
|
||||
|
||||
void MASK_OT_shape_key_insert(wmOperatorType *ot)
|
||||
{
|
||||
/* identifiers */
|
||||
ot->name = "Insert Shape Key";
|
||||
ot->description = "";
|
||||
ot->idname = "MASK_OT_shape_key_insert";
|
||||
|
||||
/* api callbacks */
|
||||
ot->exec = mask_shape_key_insert_exec;
|
||||
ot->poll = ED_maskediting_mask_poll;
|
||||
|
||||
/* flags */
|
||||
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
|
||||
}
|
||||
|
||||
static int mask_shape_key_clear_exec(bContext *C, wmOperator *UNUSED(op))
|
||||
{
|
||||
Scene *scene = CTX_data_scene(C);
|
||||
const int frame = CFRA;
|
||||
Mask *mask = CTX_data_edit_mask(C);
|
||||
MaskObject *maskobj;
|
||||
|
||||
for (maskobj = mask->maskobjs.first; maskobj; maskobj = maskobj->next) {
|
||||
MaskObjectShape *maskobj_shape;
|
||||
|
||||
maskobj_shape = BKE_mask_object_shape_find_frame(maskobj, frame);
|
||||
|
||||
if (maskobj_shape) {
|
||||
BKE_mask_object_shape_unlink(maskobj, maskobj_shape);
|
||||
}
|
||||
}
|
||||
|
||||
WM_event_add_notifier(C, NC_MASK | ND_DATA, mask);
|
||||
DAG_id_tag_update(&mask->id, 0);
|
||||
|
||||
return OPERATOR_FINISHED;
|
||||
}
|
||||
|
||||
void MASK_OT_shape_key_clear(wmOperatorType *ot)
|
||||
{
|
||||
/* identifiers */
|
||||
ot->name = "Clear Shape Key";
|
||||
ot->description = "";
|
||||
ot->idname = "MASK_OT_shape_key_clear";
|
||||
|
||||
/* api callbacks */
|
||||
ot->exec = mask_shape_key_clear_exec;
|
||||
ot->poll = ED_maskediting_mask_poll;
|
||||
|
||||
/* flags */
|
||||
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
|
||||
}
|
||||
@@ -85,12 +85,23 @@ typedef struct MaskSpline {
|
||||
int weight_interp, pad; /* weight interpolation */
|
||||
} MaskSpline;
|
||||
|
||||
/* one per frame */
|
||||
typedef struct MaskObjectShape {
|
||||
struct MaskObjectShape *next, *prev;
|
||||
|
||||
float *data; /* u coordinate along spline segment and weight of this point */
|
||||
int tot_vert; /* to ensure no buffer overruns's: alloc size is (tot_vert * MASK_OBJECT_SHAPE_ELEM_SIZE) */
|
||||
int frame; /* different flags of this point */
|
||||
} MaskObjectShape;
|
||||
|
||||
typedef struct MaskObject {
|
||||
struct MaskObject *next, *prev;
|
||||
|
||||
char name[64]; /* name of the mask object (64 = MAD_ID_NAME - 2) */
|
||||
|
||||
ListBase splines; /* list of splines which defines this mask object */
|
||||
ListBase splines_shapes;
|
||||
|
||||
struct MaskSpline *act_spline; /* active spline */
|
||||
struct MaskSplinePoint *act_point; /* active point */
|
||||
} MaskObject;
|
||||
@@ -105,4 +116,6 @@ typedef struct MaskObject {
|
||||
#define MASK_SPLINE_INTERP_LINEAR 1
|
||||
#define MASK_SPLINE_INTERP_EASE 2
|
||||
|
||||
#define MASK_OBJECT_SHAPE_ELEM_SIZE 8 /* 3x 2D points + weight + radius == 8 */
|
||||
|
||||
#endif // __DNA_MASK_TYPES_H__
|
||||
|
||||
Reference in New Issue
Block a user