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
diff options
context:
space:
mode:
authorCampbell Barton <ideasman42@gmail.com>2012-06-04 20:42:58 +0400
committerCampbell Barton <ideasman42@gmail.com>2012-06-04 20:42:58 +0400
commit68a9dd54ec909d8e56da0da487c6ec3559551edd (patch)
tree9b0949fdc65604fe3e39b765b4085a714b8e7471 /source/blender/editors
parent2230f3346e8a7ac2191690627856a1a8745bd8e9 (diff)
mask mode for clip editor developed by Sergey Sharybin, Pete Larabell and myself.
see: http://wiki.blender.org/index.php/User:Nazg-gul/MaskEditor note - mask editing tools need continued development, feather option is not working 100%
Diffstat (limited to 'source/blender/editors')
-rw-r--r--source/blender/editors/CMakeLists.txt1
-rw-r--r--source/blender/editors/SConscript1
-rw-r--r--source/blender/editors/animation/keyframes_draw.c68
-rw-r--r--source/blender/editors/include/ED_clip.h10
-rw-r--r--source/blender/editors/include/ED_keyframes_draw.h4
-rw-r--r--source/blender/editors/include/ED_object.h1
-rw-r--r--source/blender/editors/include/ED_screen.h1
-rw-r--r--source/blender/editors/include/ED_transform.h1
-rw-r--r--source/blender/editors/interface/interface_templates.c20
-rw-r--r--source/blender/editors/object/object_ops.c8
-rw-r--r--source/blender/editors/screen/screen_ops.c22
-rw-r--r--source/blender/editors/space_api/spacetypes.c4
-rw-r--r--source/blender/editors/space_clip/clip_draw.c28
-rw-r--r--source/blender/editors/space_clip/clip_editor.c127
-rw-r--r--source/blender/editors/space_clip/space_clip.c100
-rw-r--r--source/blender/editors/space_node/drawnode.c9
-rw-r--r--source/blender/editors/space_node/space_node.c7
-rw-r--r--source/blender/editors/transform/transform.c96
-rw-r--r--source/blender/editors/transform/transform.h1
-rw-r--r--source/blender/editors/transform/transform_conversions.c230
-rw-r--r--source/blender/editors/transform/transform_generics.c66
21 files changed, 754 insertions, 51 deletions
diff --git a/source/blender/editors/CMakeLists.txt b/source/blender/editors/CMakeLists.txt
index 088376b20ef..67ed77bcc4b 100644
--- a/source/blender/editors/CMakeLists.txt
+++ b/source/blender/editors/CMakeLists.txt
@@ -24,6 +24,7 @@ if(WITH_BLENDER)
add_subdirectory(curve)
add_subdirectory(gpencil)
add_subdirectory(interface)
+ add_subdirectory(mask)
add_subdirectory(mesh)
add_subdirectory(metaball)
add_subdirectory(object)
diff --git a/source/blender/editors/SConscript b/source/blender/editors/SConscript
index ed66a76a324..d08b496f0ef 100644
--- a/source/blender/editors/SConscript
+++ b/source/blender/editors/SConscript
@@ -8,6 +8,7 @@ SConscript(['datafiles/SConscript',
'interface/SConscript',
'animation/SConscript',
'armature/SConscript',
+ 'mask/SConscript',
'mesh/SConscript',
'metaball/SConscript',
'object/SConscript',
diff --git a/source/blender/editors/animation/keyframes_draw.c b/source/blender/editors/animation/keyframes_draw.c
index cb7dc7ac206..cee8d15a807 100644
--- a/source/blender/editors/animation/keyframes_draw.c
+++ b/source/blender/editors/animation/keyframes_draw.c
@@ -60,6 +60,7 @@
#include "DNA_speaker_types.h"
#include "DNA_world_types.h"
#include "DNA_gpencil_types.h"
+#include "DNA_mask_types.h"
#include "BKE_key.h"
#include "BKE_material.h"
@@ -184,6 +185,50 @@ static void nupdate_ak_gpframe(void *node, void *data)
ak->modified += 1;
}
+/* ......... */
+
+/* Comparator callback used for ActKeyColumns and GPencil frame */
+static short compare_ak_masklayshape(void *node, void *data)
+{
+ ActKeyColumn *ak = (ActKeyColumn *)node;
+ MaskLayerShape *masklay_shape = (MaskLayerShape *)data;
+
+ if (masklay_shape->frame < ak->cfra)
+ return -1;
+ else if (masklay_shape->frame > ak->cfra)
+ return 1;
+ else
+ return 0;
+}
+
+/* New node callback used for building ActKeyColumns from GPencil frames */
+static DLRBT_Node *nalloc_ak_masklayshape(void *data)
+{
+ ActKeyColumn *ak = MEM_callocN(sizeof(ActKeyColumn), "ActKeyColumnGPF");
+ MaskLayerShape *masklay_shape = (MaskLayerShape *)data;
+
+ /* store settings based on state of BezTriple */
+ ak->cfra = masklay_shape->frame;
+ ak->sel = (masklay_shape->flag & SELECT) ? SELECT : 0;
+
+ /* set 'modified', since this is used to identify long keyframes */
+ ak->modified = 1;
+
+ return (DLRBT_Node *)ak;
+}
+
+/* Node updater callback used for building ActKeyColumns from GPencil frames */
+static void nupdate_ak_masklayshape(void *node, void *data)
+{
+ ActKeyColumn *ak = (ActKeyColumn *)node;
+ MaskLayerShape *masklay_shape = (MaskLayerShape *)data;
+
+ /* set selection status and 'touched' status */
+ if (masklay_shape->flag & SELECT) ak->sel = SELECT;
+ ak->modified += 1;
+}
+
+
/* --------------- */
/* Add the given BezTriple to the given 'list' of Keyframes */
@@ -204,6 +249,15 @@ static void add_gpframe_to_keycolumns_list(DLRBT_Tree *keys, bGPDframe *gpf)
BLI_dlrbTree_add(keys, compare_ak_gpframe, nalloc_ak_gpframe, nupdate_ak_gpframe, gpf);
}
+/* Add the given MaskLayerShape Frame to the given 'list' of Keyframes */
+static void add_masklay_to_keycolumns_list(DLRBT_Tree *keys, MaskLayerShape *masklay_shape)
+{
+ if (ELEM(NULL, keys, masklay_shape))
+ return;
+ else
+ BLI_dlrbTree_add(keys, compare_ak_masklayshape, nalloc_ak_masklayshape, nupdate_ak_masklayshape, masklay_shape);
+}
+
/* ActBeztColumns (Helpers for Long Keyframes) ------------------------------ */
/* maximum size of default buffer for BezTriple columns */
@@ -940,3 +994,17 @@ void gpl_to_keylist(bDopeSheet *UNUSED(ads), bGPDlayer *gpl, DLRBT_Tree *keys)
}
}
+void mask_to_keylist(bDopeSheet *UNUSED(ads), MaskLayer *masklay, DLRBT_Tree *keys)
+{
+ MaskLayerShape *masklay_shape;
+
+ if (masklay && keys) {
+ for (masklay_shape = masklay->splines_shapes.first;
+ masklay_shape;
+ masklay_shape = masklay_shape->next)
+ {
+ add_masklay_to_keycolumns_list(keys, masklay_shape);
+ }
+ }
+}
+
diff --git a/source/blender/editors/include/ED_clip.h b/source/blender/editors/include/ED_clip.h
index 7943a17c377..7e1505b652f 100644
--- a/source/blender/editors/include/ED_clip.h
+++ b/source/blender/editors/include/ED_clip.h
@@ -36,6 +36,7 @@ struct bContext;
struct bScreen;
struct ImBuf;
struct Main;
+struct Mask;
struct MovieClip;
struct SpaceClip;
struct wmEvent;
@@ -48,12 +49,19 @@ int ED_space_clip_view_clip_poll(struct bContext *C);
int ED_space_clip_tracking_poll(struct bContext *C);
int ED_space_clip_tracking_size_poll(struct bContext *C);
int ED_space_clip_tracking_frame_poll(struct bContext *C);
+int ED_space_clip_maskediting_poll(struct bContext *C);
+int ED_space_clip_maskediting_mask_poll(bContext *C);
void ED_space_clip_set(struct bContext *C, struct bScreen *screen, struct SpaceClip *sc, struct MovieClip *clip);
struct MovieClip *ED_space_clip(struct SpaceClip *sc);
+struct Mask *ED_space_clip_mask(struct SpaceClip *sc);
void ED_space_clip_size(struct SpaceClip *sc, int *width, int *height);
void ED_space_clip_zoom(struct SpaceClip *sc, ARegion *ar, float *zoomx, float *zoomy);
void ED_space_clip_aspect(struct SpaceClip *sc, float *aspx, float *aspy);
+void ED_space_clip_aspect_dimension_aware(struct SpaceClip *sc, float *aspx, float *aspy);
+
+void ED_space_clip_mask_size(struct SpaceClip *sc, int *width, int *height);
+void ED_space_clip_mask_aspect(struct SpaceClip *sc, float *aspx, float *aspy);
struct ImBuf *ED_space_clip_get_buffer(struct SpaceClip *sc);
struct ImBuf *ED_space_clip_get_stable_buffer(struct SpaceClip *sc, float loc[2], float *scale, float *angle);
@@ -72,6 +80,8 @@ void ED_space_clip_unload_movieclip_buffer(struct SpaceClip *sc);
void ED_space_clip_free_texture_buffer(struct SpaceClip *sc);
int ED_space_clip_show_trackedit(struct SpaceClip *sc);
+int ED_space_clip_show_maskedit(struct SpaceClip *sc);
+void ED_space_clip_set_mask(struct bContext *C, struct SpaceClip *sc, struct Mask *mask);
/* clip_ops.c */
void ED_operatormacros_clip(void);
diff --git a/source/blender/editors/include/ED_keyframes_draw.h b/source/blender/editors/include/ED_keyframes_draw.h
index cd64427de78..e24c21bc133 100644
--- a/source/blender/editors/include/ED_keyframes_draw.h
+++ b/source/blender/editors/include/ED_keyframes_draw.h
@@ -42,6 +42,7 @@ struct bActionGroup;
struct Object;
struct ListBase;
struct bGPDlayer;
+struct MaskLayer;
struct Scene;
struct View2D;
struct DLRBT_Tree;
@@ -139,6 +140,9 @@ void summary_to_keylist(struct bAnimContext *ac, struct DLRBT_Tree *keys, struct
/* Grease Pencil Layer */
// XXX not restored
void gpl_to_keylist(struct bDopeSheet *ads, struct bGPDlayer *gpl, struct DLRBT_Tree *keys);
+/* Mask */
+// XXX not restored
+void mask_to_keylist(struct bDopeSheet *UNUSED(ads), struct MaskLayer *masklay, struct DLRBT_Tree *keys);
/* ActKeyColumn API ---------------- */
/* Comparator callback used for ActKeyColumns and cframe float-value pointer */
diff --git a/source/blender/editors/include/ED_object.h b/source/blender/editors/include/ED_object.h
index 8dc83df2977..9c10a270ef8 100644
--- a/source/blender/editors/include/ED_object.h
+++ b/source/blender/editors/include/ED_object.h
@@ -90,6 +90,7 @@ struct Base *ED_object_scene_link(struct Scene *scene, struct Object *ob);
void ED_keymap_proportional_cycle(struct wmKeyConfig *keyconf, struct wmKeyMap *keymap);
void ED_keymap_proportional_obmode(struct wmKeyConfig *keyconf, struct wmKeyMap *keymap);
+void ED_keymap_proportional_maskmode(struct wmKeyConfig *keyconf, struct wmKeyMap *keymap);
void ED_keymap_proportional_editmode(struct wmKeyConfig *keyconf, struct wmKeyMap *keymap,
const short do_connected);
diff --git a/source/blender/editors/include/ED_screen.h b/source/blender/editors/include/ED_screen.h
index 464f2db30a2..4faf82eec36 100644
--- a/source/blender/editors/include/ED_screen.h
+++ b/source/blender/editors/include/ED_screen.h
@@ -170,6 +170,7 @@ int ED_operator_editmball(struct bContext *C);
int ED_operator_uvedit(struct bContext *C);
int ED_operator_uvmap(struct bContext *C);
int ED_operator_posemode(struct bContext *C);
+int ED_operator_mask(struct bContext *C);
/* default keymaps, bitflags */
diff --git a/source/blender/editors/include/ED_transform.h b/source/blender/editors/include/ED_transform.h
index 3bef1f56655..d867532b273 100644
--- a/source/blender/editors/include/ED_transform.h
+++ b/source/blender/editors/include/ED_transform.h
@@ -96,6 +96,7 @@ enum {
#define CTX_BMESH 64
#define CTX_NDOF 128
#define CTX_MOVIECLIP 256
+#define CTX_MASK 512
/* Standalone call to get the transformation center corresponding to the current situation
* returns 1 if successful, 0 otherwise (usually means there's no selection)
diff --git a/source/blender/editors/interface/interface_templates.c b/source/blender/editors/interface/interface_templates.c
index 59ef0c00283..daba096696c 100644
--- a/source/blender/editors/interface/interface_templates.c
+++ b/source/blender/editors/interface/interface_templates.c
@@ -579,8 +579,10 @@ void uiTemplateAnyID(uiLayout *layout, PointerRNA *ptr, const char *propname, co
row = uiLayoutRow(layout, 1);
/* Label - either use the provided text, or will become "ID-Block:" */
- if (text)
- uiItemL(row, text, ICON_NONE);
+ if (text) {
+ if (text[0])
+ uiItemL(row, text, ICON_NONE);
+ }
else
uiItemL(row, "ID-Block:", ICON_NONE);
@@ -2239,6 +2241,20 @@ static void list_item_row(bContext *C, uiLayout *layout, PointerRNA *ptr, Pointe
uiItemL(split, name, ICON_OBJECT_DATA);
}
}
+ else if (itemptr->type == &RNA_MaskLayer) {
+ split = uiLayoutSplit(sub, 0.66f, 0);
+
+ uiItemL(split, name, icon);
+
+ uiBlockSetEmboss(block, UI_EMBOSSN);
+ row = uiLayoutRow(split, 1);
+ // uiItemR(row, itemptr, "alpha", 0, "", ICON_NONE); // enable when used
+ uiItemR(row, itemptr, "hide", 0, "", 0);
+ uiItemR(row, itemptr, "hide_select", 0, "", 0);
+ uiItemR(row, itemptr, "hide_render", 0, "", 0);
+
+ uiBlockSetEmboss(block, UI_EMBOSS);
+ }
/* There is a last chance to display custom controls (in addition to the name/label):
* If the given item property group features a string property named as prop_list,
diff --git a/source/blender/editors/object/object_ops.c b/source/blender/editors/object/object_ops.c
index 6e653eff57c..d0a93302b7f 100644
--- a/source/blender/editors/object/object_ops.c
+++ b/source/blender/editors/object/object_ops.c
@@ -441,6 +441,14 @@ void ED_keymap_proportional_obmode(struct wmKeyConfig *UNUSED(keyconf), struct w
RNA_string_set(kmi->ptr, "data_path", "tool_settings.use_proportional_edit_objects");
}
+void ED_keymap_proportional_maskmode(struct wmKeyConfig *UNUSED(keyconf), struct wmKeyMap *keymap)
+{
+ wmKeyMapItem *kmi;
+
+ kmi = WM_keymap_add_item(keymap, "WM_OT_context_toggle", OKEY, KM_PRESS, 0, 0);
+ RNA_string_set(kmi->ptr, "data_path", "tool_settings.use_proportional_edit_mask");
+}
+
void ED_keymap_proportional_editmode(struct wmKeyConfig *UNUSED(keyconf), struct wmKeyMap *keymap,
const short do_connected)
{
diff --git a/source/blender/editors/screen/screen_ops.c b/source/blender/editors/screen/screen_ops.c
index 8baca253519..89c7896d53c 100644
--- a/source/blender/editors/screen/screen_ops.c
+++ b/source/blender/editors/screen/screen_ops.c
@@ -46,6 +46,7 @@
#include "DNA_scene_types.h"
#include "DNA_meta_types.h"
#include "DNA_mesh_types.h"
+#include "DNA_mask_types.h"
#include "DNA_userdef_types.h"
#include "BKE_context.h"
@@ -59,6 +60,7 @@
#include "BKE_screen.h"
#include "BKE_tessmesh.h"
#include "BKE_sound.h"
+#include "BKE_mask.h"
#include "WM_api.h"
#include "WM_types.h"
@@ -71,6 +73,7 @@
#include "ED_screen_types.h"
#include "ED_keyframes_draw.h"
#include "ED_view3d.h"
+#include "ED_clip.h"
#include "RNA_access.h"
#include "RNA_define.h"
@@ -453,6 +456,13 @@ int ED_operator_editmball(bContext *C)
return 0;
}
+int ED_operator_mask(bContext *C)
+{
+ SpaceClip *sc= CTX_wm_space_clip(C);
+
+ return ED_space_clip_show_maskedit(sc);
+}
+
/* *************************** action zone operator ************************** */
/* operator state vars used:
@@ -1937,7 +1947,17 @@ static int keyframe_jump_exec(bContext *C, wmOperator *op)
if (ob)
ob_to_keylist(&ads, ob, &keys, NULL);
-
+
+ {
+ SpaceClip *sc = CTX_wm_space_clip(C);
+ if (sc) {
+ if ((sc->mode == SC_MODE_MASKEDITING) && sc->mask) {
+ MaskLayer *masklay = BKE_mask_layer_active(sc->mask);
+ mask_to_keylist(&ads, masklay, &keys);
+ }
+ }
+ }
+
/* build linked-list for searching */
BLI_dlrbTree_linkedlist_sync(&keys);
diff --git a/source/blender/editors/space_api/spacetypes.c b/source/blender/editors/space_api/spacetypes.c
index 956aee84fd3..fa77249a7a1 100644
--- a/source/blender/editors/space_api/spacetypes.c
+++ b/source/blender/editors/space_api/spacetypes.c
@@ -62,6 +62,7 @@
#include "ED_mball.h"
#include "ED_logic.h"
#include "ED_clip.h"
+#include "ED_mask.h"
/* only call once on startup, storage is global in BKE kernel listbase */
void ED_spacetypes_init(void)
@@ -111,6 +112,7 @@ void ED_spacetypes_init(void)
ED_operatortypes_sound();
ED_operatortypes_render();
ED_operatortypes_logic();
+ ED_operatortypes_mask();
UI_view2d_operatortypes();
UI_buttons_operatortypes();
@@ -133,6 +135,7 @@ void ED_spacetypes_init(void)
ED_operatormacros_action();
ED_operatormacros_clip();
ED_operatormacros_curve();
+ ED_operatormacros_mask();
/* register dropboxes (can use macros) */
spacetypes = BKE_spacetypes_list();
@@ -164,6 +167,7 @@ void ED_spacetypes_keymap(wmKeyConfig *keyconf)
ED_keymap_physics(keyconf);
ED_keymap_metaball(keyconf);
ED_keymap_paint(keyconf);
+ ED_keymap_mask(keyconf);
ED_marker_keymap(keyconf);
UI_view2d_keymap(keyconf);
diff --git a/source/blender/editors/space_clip/clip_draw.c b/source/blender/editors/space_clip/clip_draw.c
index c00359f0f32..6ac5ec59742 100644
--- a/source/blender/editors/space_clip/clip_draw.c
+++ b/source/blender/editors/space_clip/clip_draw.c
@@ -33,12 +33,14 @@
#include "DNA_movieclip_types.h"
#include "DNA_scene_types.h"
#include "DNA_object_types.h" /* SELECT */
+#include "DNA_mask_types.h"
#include "MEM_guardedalloc.h"
#include "BKE_context.h"
#include "BKE_movieclip.h"
#include "BKE_tracking.h"
+#include "BKE_mask.h"
#include "IMB_imbuf_types.h"
#include "IMB_imbuf.h"
@@ -194,6 +196,32 @@ static void draw_movieclip_cache(SpaceClip *sc, ARegion *ar, MovieClip *clip, Sc
glRecti(x, 0, x + framelen, 8);
clip_draw_curfra_label(sc, x, 8.0f);
+
+ /* movie clip animation */
+ if ((sc->mode == SC_MODE_MASKEDITING) && sc->mask) {
+ MaskLayer *masklay = BKE_mask_layer_active(sc->mask);
+ if (masklay) {
+ MaskLayerShape *masklay_shape;
+
+ glColor4ub(255, 175, 0, 255);
+ glBegin(GL_LINES);
+
+ for (masklay_shape = masklay->splines_shapes.first;
+ masklay_shape;
+ masklay_shape = masklay_shape->next)
+ {
+ i = masklay_shape->frame;
+
+ /* glRecti((i - sfra) * framelen, 0, (i - sfra + 1) * framelen, 4); */
+
+ /* use a line so we always see the keyframes */
+ glVertex2i((i - sfra) * framelen, 0);
+ glVertex2i((i - sfra) * framelen, (i == CFRA) ? 22 : 10);
+ }
+
+ glEnd();
+ }
+ }
}
static void draw_movieclip_notes(SpaceClip *sc, ARegion *ar)
diff --git a/source/blender/editors/space_clip/clip_editor.c b/source/blender/editors/space_clip/clip_editor.c
index a477a7435fd..f16ef21b707 100644
--- a/source/blender/editors/space_clip/clip_editor.c
+++ b/source/blender/editors/space_clip/clip_editor.c
@@ -34,10 +34,12 @@
#include "MEM_guardedalloc.h"
#include "BKE_main.h"
+#include "BKE_mask.h"
#include "BKE_movieclip.h"
#include "BKE_context.h"
#include "BKE_tracking.h"
+#include "DNA_mask_types.h"
#include "DNA_object_types.h" /* SELECT */
#include "BLI_utildefines.h"
@@ -127,6 +129,32 @@ int ED_space_clip_tracking_frame_poll(bContext *C)
return FALSE;
}
+int ED_space_clip_maskediting_poll(bContext *C)
+{
+ SpaceClip *sc = CTX_wm_space_clip(C);
+
+ if (sc && sc->clip) {
+ return ED_space_clip_show_maskedit(sc);
+ }
+
+ return FALSE;
+}
+
+int ED_space_clip_maskediting_mask_poll(bContext *C)
+{
+ if (ED_space_clip_maskediting_poll(C)) {
+ MovieClip *clip = CTX_data_edit_movieclip(C);
+
+ if (clip) {
+ SpaceClip *sc= CTX_wm_space_clip(C);
+
+ return sc->mask != NULL;
+ }
+ }
+
+ return FALSE;
+}
+
/* ******** editing functions ******** */
void ED_space_clip_set(bContext *C, bScreen *screen, SpaceClip *sc, MovieClip *clip)
@@ -170,6 +198,11 @@ MovieClip *ED_space_clip(SpaceClip *sc)
return sc->clip;
}
+Mask *ED_space_clip_mask(SpaceClip *sc)
+{
+ return sc->mask;
+}
+
ImBuf *ED_space_clip_get_buffer(SpaceClip *sc)
{
if (sc->clip) {
@@ -214,6 +247,51 @@ void ED_space_clip_size(SpaceClip *sc, int *width, int *height)
}
}
+void ED_space_clip_mask_size(SpaceClip *sc, int *width, int *height)
+{
+ /* quite the same as ED_space_clip_size, but it also runs aspect correction on output resolution
+ * this is needed because mask should be rasterized with exactly the same resolution as
+ * currently displaying frame and it doesn't have access to aspect correction currently
+ * used for display. (sergey)
+ */
+
+ if (!sc->mask) {
+ *width = 0;
+ *height = 0;
+ } else {
+ float aspx, aspy;
+
+ ED_space_clip_size(sc, width, height);
+ ED_space_clip_aspect(sc, &aspx, &aspy);
+
+ *width *= aspx;
+ *height *= aspy;
+ }
+}
+
+void ED_space_clip_mask_aspect(SpaceClip *sc, float *aspx, float *aspy)
+{
+ int w, h;
+
+ ED_space_clip_aspect(sc, aspx, aspy);
+ ED_space_clip_size(sc, &w, &h);
+
+ /* now this is not accounted for! */
+#if 0
+ *aspx *= (float)w;
+ *aspy *= (float)h;
+#endif
+
+ if(*aspx < *aspy) {
+ *aspy= *aspy / *aspx;
+ *aspx= 1.0f;
+ }
+ else {
+ *aspx= *aspx / *aspy;
+ *aspy= 1.0f;
+ }
+}
+
void ED_space_clip_zoom(SpaceClip *sc, ARegion *ar, float *zoomx, float *zoomy)
{
int width, height;
@@ -234,6 +312,33 @@ void ED_space_clip_aspect(SpaceClip *sc, float *aspx, float *aspy)
*aspx = *aspy = 1.0f;
}
+void ED_space_clip_aspect_dimension_aware(SpaceClip *sc, float *aspx, float *aspy)
+{
+ int w, h;
+
+ /* most of tools does not require aspect to be returned with dimensions correction
+ * due to they're invariant to this stuff, but some transformation tools like rotation
+ * should be aware of aspect correction caused by different resolution in different
+ * directions.
+ * mainly this is sued for transformation stuff
+ */
+
+ ED_space_clip_aspect(sc, aspx, aspy);
+ ED_space_clip_size(sc, &w, &h);
+
+ *aspx *= (float)w;
+ *aspy *= (float)h;
+
+ if(*aspx < *aspy) {
+ *aspy= *aspy / *aspx;
+ *aspx= 1.0f;
+ }
+ else {
+ *aspx= *aspx / *aspy;
+ *aspy= 1.0f;
+ }
+}
+
void ED_clip_update_frame(const Main *mainp, int cfra)
{
wmWindowManager *wm;
@@ -562,6 +667,8 @@ void ED_space_clip_free_texture_buffer(SpaceClip *sc)
}
}
+/* ******** masking editing related functions ******** */
+
int ED_space_clip_show_trackedit(SpaceClip *sc)
{
if (sc) {
@@ -570,3 +677,23 @@ int ED_space_clip_show_trackedit(SpaceClip *sc)
return FALSE;
}
+
+int ED_space_clip_show_maskedit(SpaceClip *sc)
+{
+ if (sc) {
+ return sc->mode == SC_MODE_MASKEDITING;
+ }
+
+ return FALSE;
+}
+
+void ED_space_clip_set_mask(bContext *C, SpaceClip *sc, Mask *mask)
+{
+ sc->mask = mask;
+
+ if(sc->mask && sc->mask->id.us==0)
+ sc->clip->id.us = 1;
+
+ if(C)
+ WM_event_add_notifier(C, NC_MASK|NA_SELECTED, mask);
+}
diff --git a/source/blender/editors/space_clip/space_clip.c b/source/blender/editors/space_clip/space_clip.c
index a6fda200ff4..5e04d5c99cd 100644
--- a/source/blender/editors/space_clip/space_clip.c
+++ b/source/blender/editors/space_clip/space_clip.c
@@ -33,7 +33,9 @@
#include <stdio.h>
#include "DNA_scene_types.h"
+#include "DNA_mask_types.h"
#include "DNA_movieclip_types.h"
+#include "DNA_view3d_types.h" /* for pivot point */
#include "MEM_guardedalloc.h"
@@ -49,6 +51,8 @@
#include "IMB_imbuf_types.h"
+#include "ED_mask.h"
+#include "ED_space_api.h"
#include "ED_screen.h"
#include "ED_clip.h"
#include "ED_transform.h"
@@ -237,6 +241,7 @@ static SpaceLink *clip_new(const bContext *C)
sc->zoom = 1.0f;
sc->path_length = 20;
sc->scopes.track_preview_height = 120;
+ sc->around = V3D_LOCAL;
/* header */
ar = MEM_callocN(sizeof(ARegion), "header for clip");
@@ -361,6 +366,24 @@ static void clip_listener(ScrArea *sa, wmNotifier *wmn)
break;
}
break;
+ case NC_MASK:
+ switch(wmn->data) {
+ case ND_SELECT:
+ case ND_DATA:
+ case ND_DRAW:
+ ED_area_tag_redraw(sa);
+ break;
+ }
+ switch(wmn->action) {
+ case NA_SELECTED:
+ clip_scopes_tag_refresh(sa);
+ ED_area_tag_redraw(sa);
+ break;
+ case NA_EDITED:
+ ED_area_tag_redraw(sa);
+ break;
+ }
+ break;
case NC_GEOM:
switch (wmn->data) {
case ND_SELECT:
@@ -532,7 +555,7 @@ static void clip_keymap(struct wmKeyConfig *keyconf)
/* ******** Hotkeys avalaible for main region only ******** */
keymap = WM_keymap_find(keyconf, "Clip Editor", SPACE_CLIP, 0);
-
+// keymap->poll = ED_space_clip_tracking_poll;
/* ** View/navigation ** */
WM_keymap_add_item(keymap, "CLIP_OT_view_pan", MIDDLEMOUSE, KM_PRESS, 0, 0);
@@ -715,7 +738,7 @@ static void clip_keymap(struct wmKeyConfig *keyconf)
RNA_boolean_set(kmi->ptr, "extend", TRUE); /* toggle */
}
-const char *clip_context_dir[] = {"edit_movieclip", NULL};
+const char *clip_context_dir[] = {"edit_movieclip", "edit_mask", NULL};
static int clip_context(const bContext *C, const char *member, bContextDataResult *result)
{
@@ -729,7 +752,11 @@ static int clip_context(const bContext *C, const char *member, bContextDataResul
else if (CTX_data_equals(member, "edit_movieclip")) {
if (sc->clip)
CTX_data_id_pointer_set(result, &sc->clip->id);
-
+ return TRUE;
+ }
+ else if (CTX_data_equals(member, "edit_mask")) {
+ if (sc->mask)
+ CTX_data_id_pointer_set(result, &sc->mask->id);
return TRUE;
}
@@ -1020,6 +1047,9 @@ static void clip_main_area_init(wmWindowManager *wm, ARegion *ar)
UI_view2d_region_reinit(&ar->v2d, V2D_COMMONVIEW_STANDARD, ar->winx, ar->winy);
/* own keymap */
+ keymap= WM_keymap_find(wm->defaultconf, "Mask Editor", 0, 0);
+ WM_event_add_keymap_handler_bb(&ar->handlers, keymap, &ar->v2d.mask, &ar->winrct);
+
keymap = WM_keymap_find(wm->defaultconf, "Clip", SPACE_CLIP, 0);
WM_event_add_keymap_handler_bb(&ar->handlers, keymap, &ar->v2d.mask, &ar->winrct);
@@ -1067,6 +1097,49 @@ static void clip_main_area_draw(const bContext *C, ARegion *ar)
/* Grease Pencil */
clip_draw_grease_pencil((bContext *)C, 1);
+ if(sc->mode == SC_MODE_MASKEDITING) {
+ int x, y;
+ int width, height;
+ float zoomx, zoomy, aspx, aspy;
+
+ /* frame image */
+ float maxdim;
+ float xofs, yofs;
+
+ /* find window pixel coordinates of origin */
+ UI_view2d_to_region_no_clip(&ar->v2d, 0.0f, 0.0f, &x, &y);
+
+ ED_space_clip_size(sc, &width, &height);
+ ED_space_clip_zoom(sc, ar, &zoomx, &zoomy);
+ ED_space_clip_aspect(sc, &aspx, &aspy);
+
+ /* frame the image */
+ maxdim = maxf(width, height);
+ if (width == height) {
+ xofs = yofs = 0;
+ }
+ else if (width < height) {
+ xofs = ((height - width) / -2.0f) * zoomx;
+ yofs = 0.0f;
+ }
+ else { /* (width > height) */
+ xofs = 0.0f;
+ yofs = ((width - height) / -2.0f) * zoomy;
+ }
+
+ /* apply transformation so mask editing tools will assume drawing from the origin in normalized space */
+ glPushMatrix();
+ glTranslatef(x + xofs, y + yofs, 0);
+ glScalef(maxdim * zoomx, maxdim * zoomy, 0);
+ glMultMatrixf(sc->stabmat);
+
+ ED_mask_draw((bContext *)C, sc->mask_draw_flag, sc->mask_draw_type);
+
+ ED_region_draw_cb_draw(C, ar, REGION_DRAW_POST_VIEW);
+
+ glPopMatrix();
+ }
+
/* reset view matrix */
UI_view2d_view_restore(C);
@@ -1241,6 +1314,26 @@ static void clip_header_area_draw(const bContext *C, ARegion *ar)
ED_region_header(C, ar);
}
+static void clip_header_area_listener(ARegion *ar, wmNotifier *wmn)
+{
+ /* context changes */
+ switch (wmn->category) {
+ case NC_SCENE:
+ switch (wmn->data) {
+ /* for proportional editmode only */
+ case ND_TOOLSETTINGS:
+ /* TODO - should do this when in mask mode only but no datas available */
+ // if(sc->mode == SC_MODE_MASKEDITING)
+ {
+ ED_region_tag_redraw(ar);
+ }
+ break;
+ }
+ break;
+ }
+}
+
+
/****************** tools region ******************/
/* add handlers, stuff you only do once or on area/region changes */
@@ -1402,6 +1495,7 @@ void ED_spacetype_clip(void)
art->init = clip_header_area_init;
art->draw = clip_header_area_draw;
+ art->listener = clip_header_area_listener;
BLI_addhead(&st->regiontypes, art);
diff --git a/source/blender/editors/space_node/drawnode.c b/source/blender/editors/space_node/drawnode.c
index 73ca9097610..5a8bc5da324 100644
--- a/source/blender/editors/space_node/drawnode.c
+++ b/source/blender/editors/space_node/drawnode.c
@@ -2400,6 +2400,11 @@ static void node_composit_buts_viewer_but(uiLayout *layout, bContext *UNUSED(C),
}
}
+static void node_composit_buts_mask(uiLayout *layout, bContext *C, PointerRNA *ptr)
+{
+ uiTemplateID(layout, C, ptr, "mask", NULL, NULL, NULL);
+}
+
/* only once called */
static void node_composit_set_butfunc(bNodeType *ntype)
{
@@ -2589,7 +2594,9 @@ static void node_composit_set_butfunc(bNodeType *ntype)
ntype->uifuncbut = node_composit_buts_viewer_but;
ntype->uibackdropfunc = node_composit_backdrop_viewer;
break;
-
+ case CMP_NODE_MASK:
+ ntype->uifunc= node_composit_buts_mask;
+ break;
default:
ntype->uifunc = NULL;
}
diff --git a/source/blender/editors/space_node/space_node.c b/source/blender/editors/space_node/space_node.c
index 520a9f1cd22..66919935d48 100644
--- a/source/blender/editors/space_node/space_node.c
+++ b/source/blender/editors/space_node/space_node.c
@@ -245,6 +245,13 @@ static void node_area_listener(ScrArea *sa, wmNotifier *wmn)
break;
}
break;
+ case NC_MASK:
+ if (wmn->action == NA_EDITED) {
+ if (type==NTREE_COMPOSIT) {
+ ED_area_tag_refresh(sa);
+ }
+ }
+ break;
case NC_IMAGE:
if (wmn->action == NA_EDITED) {
diff --git a/source/blender/editors/transform/transform.c b/source/blender/editors/transform/transform.c
index e955dae0178..157fe1aa710 100644
--- a/source/blender/editors/transform/transform.c
+++ b/source/blender/editors/transform/transform.c
@@ -49,6 +49,7 @@
#include "DNA_constraint_types.h"
#include "DNA_mesh_types.h"
#include "DNA_meshdata_types.h"
+#include "DNA_mask_types.h"
#include "DNA_movieclip_types.h"
#include "DNA_scene_types.h" /* PET modes */
@@ -162,13 +163,35 @@ void convertViewVec(TransInfo *t, float r_vec[3], int dx, int dy)
else if (t->spacetype==SPACE_CLIP) {
View2D *v2d = t->view;
float divx, divy;
+ float mulx, muly;
+ float aspx = 1.0f, aspy = 1.0f;
divx = v2d->mask.xmax-v2d->mask.xmin;
divy = v2d->mask.ymax-v2d->mask.ymin;
- r_vec[0] = (v2d->cur.xmax-v2d->cur.xmin)*(dx)/divx;
- r_vec[1] = (v2d->cur.ymax-v2d->cur.ymin)*(dy)/divy;
+ mulx = (v2d->cur.xmax-v2d->cur.xmin);
+ muly = (v2d->cur.ymax-v2d->cur.ymin);
+
+ if (t->options & CTX_MASK) {
+ /* clamp w/h, mask only */
+ divx = divy = maxf(divx, divy);
+ mulx = muly = minf(mulx, muly);
+ }
+
+ r_vec[0] = mulx * (dx) / divx;
+ r_vec[1] = muly * (dy) / divy;
r_vec[2] = 0.0f;
+
+ if (t->options & CTX_MOVIECLIP) {
+ ED_space_clip_aspect_dimension_aware(t->sa->spacedata.first, &aspx, &aspy);
+ }
+ else if (t->options & CTX_MASK) {
+ /* TODO - NOT WORKING, this isnt so bad since its only display aspect */
+ ED_space_clip_mask_aspect(t->sa->spacedata.first, &aspx, &aspy);
+ }
+
+ r_vec[0] *= aspx;
+ r_vec[1] *= aspy;
}
else {
printf("%s: called in an invalid context\n", __func__);
@@ -226,9 +249,18 @@ void projectIntView(TransInfo *t, const float vec[3], int adr[2])
}
else if (t->spacetype==SPACE_CLIP) {
float v[2];
+ float aspx = 1.0f, aspy = 1.0f;
copy_v2_v2(v, vec);
+ if (t->options & CTX_MOVIECLIP)
+ ED_space_clip_aspect_dimension_aware(t->sa->spacedata.first, &aspx, &aspy);
+ else if (t->options & CTX_MASK)
+ ED_space_clip_mask_aspect(t->sa->spacedata.first, &aspx, &aspy);
+
+ v[0] /= aspx;
+ v[1] /= aspy;
+
UI_view2d_to_region_no_clip(t->view, v[0], v[1], adr, adr+1);
}
}
@@ -279,16 +311,23 @@ void applyAspectRatio(TransInfo *t, float vec[2])
vec[1] /= aspy;
}
else if ((t->spacetype==SPACE_CLIP) && (t->mode==TFM_TRANSLATION)) {
- if (t->options & CTX_MOVIECLIP) {
+ if (t->options & (CTX_MOVIECLIP | CTX_MASK)) {
SpaceClip *sc = t->sa->spacedata.first;
float aspx, aspy;
- int width, height;
- ED_space_clip_size(sc, &width, &height);
- ED_space_clip_aspect(sc, &aspx, &aspy);
- vec[0] *= width / aspx;
- vec[1] *= height / aspy;
+ if (t->options & CTX_MOVIECLIP) {
+ ED_space_clip_aspect_dimension_aware(sc, &aspx, &aspy);
+
+ vec[0] /= aspx;
+ vec[1] /= aspy;
+ }
+ else if (t->options & CTX_MASK) {
+ ED_space_clip_mask_aspect(sc, &aspx, &aspy);
+
+ vec[0] /= aspx;
+ vec[1] /= aspy;
+ }
}
}
}
@@ -312,16 +351,19 @@ void removeAspectRatio(TransInfo *t, float vec[2])
vec[1] *= aspy;
}
else if ((t->spacetype==SPACE_CLIP) && (t->mode==TFM_TRANSLATION)) {
- if (t->options & CTX_MOVIECLIP) {
+ if (t->options & (CTX_MOVIECLIP | CTX_MASK)) {
SpaceClip *sc = t->sa->spacedata.first;
- float aspx, aspy;
- int width, height;
+ float aspx = 1.0f, aspy = 1.0f;
- ED_space_clip_size(sc, &width, &height);
- ED_space_clip_aspect(sc, &aspx, &aspy);
+ if (t->options & CTX_MOVIECLIP) {
+ ED_space_clip_aspect_dimension_aware(sc, &aspx, &aspy);
+ }
+ else if (t->options & CTX_MASK) {
+ ED_space_clip_mask_aspect(sc, &aspx, &aspy);
+ }
- vec[0] *= aspx / width;
- vec[1] *= aspy / height;
+ vec[0] *= aspx;
+ vec[1] *= aspy;
}
}
}
@@ -367,12 +409,20 @@ static void viewRedrawForce(const bContext *C, TransInfo *t)
}
else if (t->spacetype==SPACE_CLIP) {
SpaceClip *sc = (SpaceClip*)t->sa->spacedata.first;
- MovieClip *clip = ED_space_clip(sc);
- /* objects could be parented to tracking data, so send this for viewport refresh */
- WM_event_add_notifier(C, NC_OBJECT|ND_TRANSFORM, NULL);
+ if (ED_space_clip_show_trackedit(sc)) {
+ MovieClip *clip = ED_space_clip(sc);
+
+ /* objects could be parented to tracking data, so send this for viewport refresh */
+ WM_event_add_notifier(C, NC_OBJECT|ND_TRANSFORM, NULL);
- WM_event_add_notifier(C, NC_MOVIECLIP|NA_EDITED, clip);
+ WM_event_add_notifier(C, NC_MOVIECLIP|NA_EDITED, clip);
+ }
+ else if (ED_space_clip_show_maskedit(sc)) {
+ Mask *mask = ED_space_clip_mask(sc);
+
+ WM_event_add_notifier(C, NC_MASK|NA_EDITED, mask);
+ }
}
}
@@ -728,7 +778,7 @@ int transformEvent(TransInfo *t, wmEvent *event)
t->redraw |= TREDRAW_HARD;
}
else if (t->mode == TFM_TRANSLATION) {
- if (t->options & CTX_MOVIECLIP) {
+ if (t->options & (CTX_MOVIECLIP | CTX_MASK)) {
restoreTransObjects(t);
t->flag ^= T_ALT_TRANSFORM;
@@ -738,7 +788,7 @@ int transformEvent(TransInfo *t, wmEvent *event)
break;
case TFM_MODAL_ROTATE:
/* only switch when... */
- if (!(t->options & CTX_TEXTURE) && !(t->options & CTX_MOVIECLIP)) {
+ if (!(t->options & CTX_TEXTURE) && !(t->options & (CTX_MOVIECLIP | CTX_MASK))) {
if ( ELEM4(t->mode, TFM_ROTATION, TFM_RESIZE, TFM_TRACKBALL, TFM_TRANSLATION) ) {
resetTransRestrictions(t);
@@ -997,7 +1047,7 @@ int transformEvent(TransInfo *t, wmEvent *event)
break;
case RKEY:
/* only switch when... */
- if (!(t->options & CTX_TEXTURE) && !(t->options & CTX_MOVIECLIP)) {
+ if (!(t->options & CTX_TEXTURE)) {
if ( ELEM4(t->mode, TFM_ROTATION, TFM_RESIZE, TFM_TRACKBALL, TFM_TRANSLATION) ) {
resetTransRestrictions(t);
@@ -1459,6 +1509,8 @@ void saveTransform(bContext *C, TransInfo *t, wmOperator *op)
{
if (t->obedit)
ts->proportional = proportional;
+ else if (t->options & CTX_MASK)
+ ts->proportional_mask = (proportional != PROP_EDIT_OFF);
else
ts->proportional_objects = (proportional != PROP_EDIT_OFF);
}
diff --git a/source/blender/editors/transform/transform.h b/source/blender/editors/transform/transform.h
index 6051fd2577b..59688f1436e 100644
--- a/source/blender/editors/transform/transform.h
+++ b/source/blender/editors/transform/transform.h
@@ -561,6 +561,7 @@ int clipUVTransform(TransInfo *t, float *vec, int resize);
void flushTransNodes(TransInfo *t);
void flushTransSeq(TransInfo *t);
void flushTransTracking(TransInfo *t);
+void flushTransMasking(TransInfo *t);
/*********************** exported from transform_manipulator.c ********** */
int gimbal_axis(struct Object *ob, float gmat[][3]); /* return 0 when no gimbal for selection */
diff --git a/source/blender/editors/transform/transform_conversions.c b/source/blender/editors/transform/transform_conversions.c
index a069194d868..9c6d7e49c08 100644
--- a/source/blender/editors/transform/transform_conversions.c
+++ b/source/blender/editors/transform/transform_conversions.c
@@ -53,6 +53,7 @@
#include "DNA_meshdata_types.h"
#include "DNA_gpencil_types.h"
#include "DNA_movieclip_types.h"
+#include "DNA_mask_types.h"
#include "MEM_guardedalloc.h"
@@ -87,6 +88,7 @@
#include "BKE_sequencer.h"
#include "BKE_tessmesh.h"
#include "BKE_tracking.h"
+#include "BKE_mask.h"
#include "ED_anim_api.h"
@@ -102,6 +104,7 @@
#include "ED_types.h"
#include "ED_uvedit.h"
#include "ED_clip.h"
+#include "ED_mask.h"
#include "ED_util.h" /* for crazyspace correction */
#include "WM_api.h" /* for WM_event_add_notifier to deal with stabilization nodes */
@@ -4897,6 +4900,24 @@ void special_aftertrans_update(bContext *C, TransInfo *t)
WM_event_add_notifier(C, NC_SCENE|ND_NODES, NULL);
}
}
+ else if (t->options & CTX_MASK) {
+ SpaceClip *sc = t->sa->spacedata.first;
+ Mask *mask = ED_space_clip_mask(sc);
+
+ if (t->scene->nodetree) {
+ /* tracks can be used for stabilization nodes,
+ * flush update for such nodes */
+ nodeUpdateID(t->scene->nodetree, &mask->id);
+ WM_event_add_notifier(C, NC_SCENE|ND_NODES, NULL);
+ }
+
+ /* TODO - dont key all masks... */
+ if (IS_AUTOKEY_ON(t->scene)) {
+ Scene *scene = t->scene;
+
+ ED_mask_layer_shape_auto_key_all(mask, CFRA);
+ }
+ }
}
else if (t->spacetype == SPACE_ACTION) {
SpaceAction *saction= (SpaceAction *)t->sa->spacedata.first;
@@ -5823,6 +5844,206 @@ void flushTransTracking(TransInfo *t)
}
}
+/* * masking * */
+
+typedef struct TransDataMasking{
+ int is_handle;
+
+ float handle[2], orig_handle[2];
+ float vec[3][3];
+ MaskSplinePoint *point;
+} TransDataMasking;
+
+static void MaskPointToTransData(SpaceClip *sc, MaskSplinePoint *point,
+ TransData *td, TransData2D *td2d, TransDataMasking *tdm, int propmode)
+{
+ BezTriple *bezt = &point->bezt;
+ float aspx, aspy;
+ short is_sel_point = MASKPOINT_ISSEL_KNOT(point);
+ short is_sel_any = MASKPOINT_ISSEL_ANY(point);
+
+ tdm->point = point;
+ copy_m3_m3(tdm->vec, bezt->vec);
+
+ ED_space_clip_mask_aspect(sc, &aspx, &aspy);
+
+ if (propmode || is_sel_point) {
+ int i;
+ for (i = 0; i < 3; i++) {
+ /* CV coords are scaled by aspects. this is needed for rotations and
+ * proportional editing to be consistent with the stretched CV coords
+ * that are displayed. this also means that for display and numinput,
+ * and when the the CV coords are flushed, these are converted each time */
+ td2d->loc[0] = bezt->vec[i][0]*aspx;
+ td2d->loc[1] = bezt->vec[i][1]*aspy;
+ td2d->loc[2] = 0.0f;
+ td2d->loc2d = bezt->vec[i];
+
+ td->flag = 0;
+ td->loc = td2d->loc;
+ copy_v3_v3(td->center, td->loc);
+ copy_v3_v3(td->iloc, td->loc);
+
+ memset(td->axismtx, 0, sizeof(td->axismtx));
+ td->axismtx[2][2] = 1.0f;
+
+ td->ext= NULL;
+ td->val= NULL;
+
+ if (is_sel_any) {
+ td->flag |= TD_SELECTED;
+ }
+ td->dist= 0.0;
+
+ unit_m3(td->mtx);
+ unit_m3(td->smtx);
+
+ td++;
+ td2d++;
+ }
+ }
+ else {
+ tdm->is_handle = TRUE;
+
+ BKE_mask_point_handle(point, tdm->handle);
+
+ copy_v2_v2(tdm->orig_handle, tdm->handle);
+
+ td2d->loc[0] = tdm->handle[0]*aspx;
+ td2d->loc[1] = tdm->handle[1]*aspy;
+ td2d->loc[2] = 0.0f;
+ td2d->loc2d = tdm->handle;
+
+ td->flag = 0;
+ td->loc = td2d->loc;
+ copy_v3_v3(td->center, td->loc);
+ copy_v3_v3(td->iloc, td->loc);
+
+ memset(td->axismtx, 0, sizeof(td->axismtx));
+ td->axismtx[2][2] = 1.0f;
+
+ td->ext= NULL;
+ td->val= NULL;
+
+ if (is_sel_any) {
+ td->flag |= TD_SELECTED;
+ }
+
+ td->dist= 0.0;
+
+ unit_m3(td->mtx);
+ unit_m3(td->smtx);
+
+ td++;
+ td2d++;
+ }
+}
+
+static void createTransMaskingData(bContext *C, TransInfo *t)
+{
+ SpaceClip *sc = CTX_wm_space_clip(C);
+ Mask *mask = CTX_data_edit_mask(C);
+ MaskLayer *masklay;
+ TransData *td = NULL;
+ TransData2D *td2d = NULL;
+ TransDataMasking *tdm = NULL;
+ int count = 0, countsel = 0;
+ int propmode = t->flag & T_PROP_EDIT;
+
+ /* count */
+ for (masklay = mask->masklayers.first; masklay; masklay = masklay->next) {
+ MaskSpline *spline = masklay->splines.first;
+
+ if (masklay->restrictflag & (MASK_RESTRICT_VIEW | MASK_RESTRICT_SELECT)) {
+ continue;
+ }
+
+ for (spline = masklay->splines.first; spline; spline = spline->next) {
+ int i;
+
+ for (i = 0; i < spline->tot_point; i++) {
+ MaskSplinePoint *point = &spline->points[i];
+
+ if (MASKPOINT_ISSEL_ANY(point)) {
+ if (MASKPOINT_ISSEL_KNOT(point))
+ countsel += 3;
+ else
+ countsel += 1;
+ }
+
+ if (propmode)
+ count += 3;
+ }
+ }
+ }
+
+ /* note: in prop mode we need at least 1 selected */
+ if (countsel == 0) return;
+
+ t->total = (propmode) ? count: countsel;
+ td = t->data = MEM_callocN(t->total*sizeof(TransData), "TransObData(Mask Editing)");
+ /* for each 2d uv coord a 3d vector is allocated, so that they can be
+ * treated just as if they were 3d verts */
+ td2d = t->data2d = MEM_callocN(t->total*sizeof(TransData2D), "TransObData2D(Mask Editing)");
+ tdm = t->customData = MEM_callocN(t->total*sizeof(TransDataMasking), "TransDataMasking(Mask Editing)");
+
+ t->flag |= T_FREE_CUSTOMDATA;
+
+ /* create data */
+ for (masklay = mask->masklayers.first; masklay; masklay = masklay->next) {
+ MaskSpline *spline = masklay->splines.first;
+
+ if (masklay->restrictflag & (MASK_RESTRICT_VIEW | MASK_RESTRICT_SELECT)) {
+ continue;
+ }
+
+ for (spline = masklay->splines.first; spline; spline = spline->next) {
+ int i;
+
+ for (i = 0; i < spline->tot_point; i++) {
+ MaskSplinePoint *point = &spline->points[i];
+
+ if (propmode || MASKPOINT_ISSEL_ANY(point)) {
+ MaskPointToTransData(sc, point, td, td2d, tdm, propmode);
+
+ if (propmode || MASKPOINT_ISSEL_KNOT(point)) {
+ td += 3;
+ td2d += 3;
+ tdm += 3;
+ }
+ else {
+ td++;
+ td2d++;
+ tdm++;
+ }
+ }
+ }
+ }
+ }
+}
+
+void flushTransMasking(TransInfo *t)
+{
+ SpaceClip *sc = t->sa->spacedata.first;
+ TransData2D *td;
+ TransDataMasking *tdm;
+ int a;
+ float aspx, aspy, invx, invy;
+
+ ED_space_clip_mask_aspect(sc, &aspx, &aspy);
+ invx = 1.0f/aspx;
+ invy = 1.0f/aspy;
+
+ /* flush to 2d vector from internally used 3d vector */
+ for(a=0, td = t->data2d, tdm = t->customData; a<t->total; a++, td++, tdm++) {
+ td->loc2d[0]= td->loc[0]*invx;
+ td->loc2d[1]= td->loc[1]*invy;
+
+ if (tdm->is_handle)
+ BKE_mask_point_set_handle(tdm->point, td->loc2d, t->flag & T_ALT_TRANSFORM, tdm->orig_handle, tdm->vec);
+ }
+}
+
void createTransData(bContext *C, TransInfo *t)
{
Scene *scene = t->scene;
@@ -5892,6 +6113,15 @@ void createTransData(bContext *C, TransInfo *t)
t->flag |= T_POINTS|T_2D_EDIT;
if (t->options & CTX_MOVIECLIP)
createTransTrackingData(C, t);
+ else if (t->options & CTX_MASK) {
+ createTransMaskingData(C, t);
+
+ if (t->data && (t->flag & T_PROP_EDIT)) {
+ sort_trans_data(t); // makes selected become first in array
+ set_prop_dist(t, TRUE);
+ sort_trans_data_dist(t);
+ }
+ }
}
else if (t->obedit) {
t->ext = NULL;
diff --git a/source/blender/editors/transform/transform_generics.c b/source/blender/editors/transform/transform_generics.c
index 0f742458ed3..3195fb0299d 100644
--- a/source/blender/editors/transform/transform_generics.c
+++ b/source/blender/editors/transform/transform_generics.c
@@ -49,6 +49,7 @@
#include "DNA_view3d_types.h"
#include "DNA_modifier_types.h"
#include "DNA_movieclip_types.h"
+#include "DNA_mask_types.h"
#include "BLI_math.h"
#include "BLI_blenlib.h"
@@ -638,33 +639,42 @@ static void recalcData_spaceclip(TransInfo *t)
{
SpaceClip *sc = t->sa->spacedata.first;
- MovieClip *clip = ED_space_clip(sc);
- ListBase *tracksbase = BKE_tracking_get_tracks(&clip->tracking);
- MovieTrackingTrack *track;
-
- flushTransTracking(t);
-
- track = tracksbase->first;
- while (track) {
- if (TRACK_VIEW_SELECTED(sc, track) && (track->flag & TRACK_LOCKED)==0) {
- if (t->mode == TFM_TRANSLATION) {
- if (TRACK_AREA_SELECTED(track, TRACK_AREA_PAT))
- BKE_tracking_clamp_track(track, CLAMP_PAT_POS);
- if (TRACK_AREA_SELECTED(track, TRACK_AREA_SEARCH))
- BKE_tracking_clamp_track(track, CLAMP_SEARCH_POS);
- }
- else if (t->mode == TFM_RESIZE) {
- if (TRACK_AREA_SELECTED(track, TRACK_AREA_PAT))
- BKE_tracking_clamp_track(track, CLAMP_PAT_DIM);
- if (TRACK_AREA_SELECTED(track, TRACK_AREA_SEARCH))
- BKE_tracking_clamp_track(track, CLAMP_SEARCH_DIM);
+ if (ED_space_clip_show_trackedit(sc)) {
+ MovieClip *clip = ED_space_clip(sc);
+ ListBase *tracksbase = BKE_tracking_get_tracks(&clip->tracking);
+ MovieTrackingTrack *track;
+
+ flushTransTracking(t);
+
+ track = tracksbase->first;
+ while (track) {
+ if (TRACK_VIEW_SELECTED(sc, track) && (track->flag & TRACK_LOCKED)==0) {
+ if (t->mode == TFM_TRANSLATION) {
+ if (TRACK_AREA_SELECTED(track, TRACK_AREA_PAT))
+ BKE_tracking_clamp_track(track, CLAMP_PAT_POS);
+ if (TRACK_AREA_SELECTED(track, TRACK_AREA_SEARCH))
+ BKE_tracking_clamp_track(track, CLAMP_SEARCH_POS);
+ }
+ else if (t->mode == TFM_RESIZE) {
+ if (TRACK_AREA_SELECTED(track, TRACK_AREA_PAT))
+ BKE_tracking_clamp_track(track, CLAMP_PAT_DIM);
+ if (TRACK_AREA_SELECTED(track, TRACK_AREA_SEARCH))
+ BKE_tracking_clamp_track(track, CLAMP_SEARCH_DIM);
+ }
}
+
+ track = track->next;
}
- track = track->next;
+ DAG_id_tag_update(&clip->id, 0);
}
+ else if (ED_space_clip_show_maskedit(sc)) {
+ Mask *mask = ED_space_clip_mask(sc);
- DAG_id_tag_update(&clip->id, 0);
+ flushTransMasking(t);
+
+ DAG_id_tag_update(&mask->id, 0);
+ }
}
/* helper for recalcData() - for 3d-view transforms */
@@ -1109,9 +1119,12 @@ int initTransInfo(bContext *C, TransInfo *t, wmOperator *op, wmEvent *event)
else if (t->spacetype==SPACE_CLIP) {
SpaceClip *sclip = sa->spacedata.first;
t->view = &ar->v2d;
+ t->around = sclip->around;
if (ED_space_clip_show_trackedit(sclip))
t->options |= CTX_MOVIECLIP;
+ else if (ED_space_clip_show_maskedit(sclip))
+ t->options |= CTX_MASK;
}
else {
if (ar) {
@@ -1174,6 +1187,15 @@ int initTransInfo(bContext *C, TransInfo *t, wmOperator *op, wmEvent *event)
t->flag |= T_PROP_CONNECTED;
}
}
+ else if (t->options & CTX_MASK) {
+ if (ts->proportional_mask) {
+ t->flag |= T_PROP_EDIT;
+
+ if (ts->proportional == PROP_EDIT_CONNECTED) {
+ t->flag |= T_PROP_CONNECTED;
+ }
+ }
+ }
else if (t->obedit == NULL && ts->proportional_objects) {
t->flag |= T_PROP_EDIT;
}