Mask primitives
authorSergey Sharybin <sergey.vfx@gmail.com>
Mon, 26 Aug 2013 20:23:26 +0000 (20:23 +0000)
committerSergey Sharybin <sergey.vfx@gmail.com>
Mon, 26 Aug 2013 20:23:26 +0000 (20:23 +0000)
Currently only circle and square, might be easily
extended in the future.

New primitives are creating at cursor location.
This also implied adding 2d cursor to space clip.

Also fix set 2D cursor location which didn't work
in image editor's mask mode since 2.67.

TODO: draw_image_cursor better be moved to some
      more generic file, but it's not so much
      important for now and might be solved later.

Thanks Campbell for the review!

18 files changed:
release/scripts/startup/bl_operators/__init__.py
release/scripts/startup/bl_operators/mask.py [new file with mode: 0644]
source/blender/editors/include/ED_mask.h
source/blender/editors/include/ED_uvedit.h
source/blender/editors/include/UI_view2d.h
source/blender/editors/interface/view2d.c
source/blender/editors/mask/mask_add.c
source/blender/editors/mask/mask_edit.c
source/blender/editors/mask/mask_intern.h
source/blender/editors/mask/mask_ops.c
source/blender/editors/space_clip/clip_draw.c
source/blender/editors/space_clip/clip_intern.h
source/blender/editors/space_clip/clip_ops.c
source/blender/editors/space_clip/space_clip.c
source/blender/editors/space_image/space_image.c
source/blender/editors/uvedit/uvedit_draw.c
source/blender/editors/uvedit/uvedit_ops.c
source/blender/makesdna/DNA_space_types.h

index 64851a3a4c13919e3767980c407031f350ee23c7..4f6863a590c9b10bef2eb34922401424ee51f622 100644 (file)
@@ -28,6 +28,7 @@ _modules = [
     "clip",
     "console",
     "image",
+    "mask",
     "mesh",
     "node",
     "object_align",
diff --git a/release/scripts/startup/bl_operators/mask.py b/release/scripts/startup/bl_operators/mask.py
new file mode 100644 (file)
index 0000000..60208d2
--- /dev/null
@@ -0,0 +1,34 @@
+# ##### 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.
+#
+# ##### END GPL LICENSE BLOCK #####
+
+# <pep8-80 compliant>
+
+import bpy
+from bpy.types import Menu
+
+
+class MASK_MT_add(Menu):
+    bl_idname = "MASK_MT_add"
+    bl_label = "Add"
+
+    def draw(self, context):
+        layout = self.layout
+
+        layout.operator_context = 'INVOKE_REGION_WIN'
+        layout.operator("mask.primitive_circle_add", text="Circle", icon='MESH_CIRCLE')
+        layout.operator("mask.primitive_square_add", text="Square", icon='MESH_PLANE')
index 420ab24e5e9df1ca8848fc99dee1c44d5901ec09..3e2dbe255dfb6a2b9ede031a3994f5a73eced77c 100644 (file)
@@ -48,6 +48,8 @@ void ED_mask_point_pos(struct ScrArea *sa, struct ARegion *ar, float x, float y,
 void ED_mask_point_pos__reverse(struct ScrArea *sa, struct ARegion *ar,
                                 float x, float y, float *xr, float *yr);
 
+void ED_mask_cursor_location_get(struct ScrArea *sa, float cursor[2]);
+
 void ED_operatortypes_mask(void);
 void ED_keymap_mask(struct wmKeyConfig *keyconf);
 void ED_operatormacros_mask(void);
index ffc9e6651bc879359bef0f6f5b3b0f6d0b597e90..735227ae9b53e884597fcc61f28e61f15a54aafb 100644 (file)
@@ -102,7 +102,7 @@ void ED_uvedit_live_unwrap(struct Scene *scene, struct Object *obedit);
 void ED_unwrap_lscm(struct Scene *scene, struct Object *obedit, const short sel);
 
 /* uvedit_draw.c */
-void draw_image_cursor(struct SpaceImage *sima, struct ARegion *ar);
+void draw_image_cursor(struct ARegion *ar, const float cursor[2]);
 void draw_uvedit_main(struct SpaceImage *sima, struct ARegion *ar, struct Scene *scene, struct Object *obedit, struct Object *obact);
 
 /* uvedit_buttons.c */
index e46334b06e73868481ca87797284a640b04d2f4e..fb70ad50b5dd1aef0aea6824d72bd2ae47ee7275 100644 (file)
@@ -192,6 +192,7 @@ void UI_view2d_listview_visible_cells(struct View2D *v2d, float columnwidth, flo
 void UI_view2d_region_to_view(struct View2D *v2d, float x, float y, float *viewx, float *viewy);
 void UI_view2d_view_to_region(struct View2D *v2d, float x, float y, int *regionx, int *regiony);
 void UI_view2d_to_region_no_clip(struct View2D *v2d, float x, float y, int *regionx, int *region_y);
+void UI_view2d_to_region_float(struct View2D *v2d, float x, float y, float *regionx, float *regiony);
 
 /* utilities */
 struct View2D *UI_view2d_fromcontext(const struct bContext *C);
index f656d22fc644269bb6259bdea6ffd5dde9941449..037fa7c6a94a9f94180fad048b30b0d0a45ef060 100644 (file)
@@ -2029,6 +2029,17 @@ void UI_view2d_to_region_no_clip(View2D *v2d, float x, float y, int *regionx, in
        }
 }
 
+void UI_view2d_to_region_float(View2D *v2d, float x, float y, float *regionx, float *regiony)
+{
+       /* express given coordinates as proportional values */
+       x = -v2d->cur.xmin / BLI_rctf_size_x(&v2d->cur);
+       y = -v2d->cur.ymin / BLI_rctf_size_y(&v2d->cur);
+
+       /* convert proportional distances to screen coordinates */
+       *regionx = v2d->mask.xmin + x * BLI_rcti_size_x(&v2d->mask);
+       *regiony = v2d->mask.ymin + y * BLI_rcti_size_y(&v2d->mask);
+}
+
 /* *********************************************************************** */
 /* Utilities */
 
index 9c270144a0ae059b7821b22cdd95b95d33f371e3..4cc9d3b59b107bbd16e2354cbe4b39e7277a8324 100644 (file)
@@ -737,3 +737,159 @@ void MASK_OT_add_feather_vertex(wmOperatorType *ot)
        RNA_def_float_vector(ot->srna, "location", 2, NULL, -FLT_MAX, FLT_MAX,
                             "Location", "Location of vertex in normalized space", -1.0f, 1.0f);
 }
+
+/******************** common primitive functions *********************/
+
+static int create_primitive_from_points(bContext *C, wmOperator *op, const float (*points)[2],
+                                        int num_points, char handle_type)
+{
+       ScrArea *sa = CTX_wm_area(C);
+       Scene *scene = CTX_data_scene(C);
+       Mask *mask;
+       MaskLayer *mask_layer;
+       MaskSpline *new_spline;
+       float scale, location[2], frame_size[2];
+       int i, width, height;
+       int size = RNA_float_get(op->ptr, "size");
+
+       ED_mask_get_size(sa, &width, &height);
+       scale = (float)size / max_ii(width, height);
+
+       /* Get location in mask space. */
+       frame_size[0] = width;
+       frame_size[1] = height;
+       RNA_float_get_array(op->ptr, "location", location);
+       location[0] /= width;
+       location[1] /= height;
+       BKE_mask_coord_from_frame(location, location, frame_size);
+
+       /* Make it so new primitive is centered to mouse location. */
+       location[0] -= 0.5f * scale;
+       location[1] -= 0.5f * scale;
+
+       mask_layer = ED_mask_layer_ensure(C);
+       mask = CTX_data_edit_mask(C);
+
+       ED_mask_select_toggle_all(mask, SEL_DESELECT);
+
+       new_spline = BKE_mask_spline_add(mask_layer);
+       new_spline->flag = MASK_SPLINE_CYCLIC | SELECT;
+       new_spline->tot_point = num_points;
+       new_spline->points = MEM_recallocN(new_spline->points,
+                                          sizeof(MaskSplinePoint) * new_spline->tot_point);
+
+       mask_layer->act_spline = new_spline;
+       mask_layer->act_point = NULL;
+
+       for (i = 0; i < num_points; i++) {
+               MaskSplinePoint *new_point = &new_spline->points[i];
+
+               copy_v2_v2(new_point->bezt.vec[1], points[i]);
+               mul_v2_fl(new_point->bezt.vec[1], scale);
+               add_v2_v2(new_point->bezt.vec[1], location);
+
+               new_point->bezt.h1 = handle_type;
+               new_point->bezt.h2 = handle_type;
+               BKE_mask_point_select_set(new_point, true);
+       }
+
+       WM_event_add_notifier(C, NC_MASK | NA_EDITED, mask);
+
+       /* TODO: only update this spline */
+       BKE_mask_update_display(mask, CFRA);
+
+       return OPERATOR_FINISHED;
+}
+
+static int primitive_add_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
+{
+       ScrArea *sa = CTX_wm_area(C);
+       float cursor[2];
+       int width, height;
+
+       ED_mask_get_size(sa, &width, &height);
+       ED_mask_cursor_location_get(sa, cursor);
+
+       cursor[0] *= width;
+       cursor[1] *= height;
+
+       RNA_float_set_array(op->ptr, "location", cursor);
+
+       return op->type->exec(C, op);
+}
+
+static void define_prinitive_add_properties(wmOperatorType *ot)
+{
+       RNA_def_float(ot->srna, "size", 100, -FLT_MAX, FLT_MAX,
+                            "Size", "Size of new circle", -FLT_MAX, FLT_MAX);
+       RNA_def_float_vector(ot->srna, "location", 2, NULL, -FLT_MAX, FLT_MAX,
+                            "Location", "Location of new circle", -FLT_MAX, FLT_MAX);
+}
+
+/******************** primitive add circle *********************/
+
+static int primitive_circle_add_exec(bContext *C, wmOperator *op)
+{
+       const float points[4][2] = {{0.0f, 0.5f},
+                                   {0.5f, 1.0f},
+                                   {1.0f, 0.5f},
+                                   {0.5f, 0.0f}};
+       int num_points = sizeof(points) / (2 * sizeof(float));
+
+       create_primitive_from_points(C, op, points, num_points, HD_AUTO);
+
+       return OPERATOR_FINISHED;
+}
+
+void MASK_OT_primitive_circle_add(wmOperatorType *ot)
+{
+       /* identifiers */
+       ot->name = "Add Circle";
+       ot->description = "Add new circle-shaped spline";
+       ot->idname = "MASK_OT_primitive_circle_add";
+
+       /* api callbacks */
+       ot->exec = primitive_circle_add_exec;
+       ot->invoke = primitive_add_invoke;
+       ot->poll = ED_operator_mask;
+
+       /* flags */
+       ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+
+       /* properties */
+       define_prinitive_add_properties(ot);
+}
+
+/******************** primitive add suqare *********************/
+
+static int primitive_square_add_exec(bContext *C, wmOperator *op)
+{
+       const float points[4][2] = {{0.0f, 0.0f},
+                                   {0.0f, 1.0f},
+                                   {1.0f, 1.0f},
+                                   {1.0f, 0.0f}};
+       int num_points = sizeof(points) / (2 * sizeof(float));
+
+       create_primitive_from_points(C, op, points, num_points, HD_VECT);
+
+       return OPERATOR_FINISHED;
+}
+
+void MASK_OT_primitive_square_add(wmOperatorType *ot)
+{
+       /* identifiers */
+       ot->name = "Add Square";
+       ot->description = "Add new square-shaped spline";
+       ot->idname = "MASK_OT_primitive_square_add";
+
+       /* api callbacks */
+       ot->exec = primitive_square_add_exec;
+       ot->invoke = primitive_add_invoke;
+       ot->poll = ED_operator_mask;
+
+       /* flags */
+       ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+
+       /* properties */
+       define_prinitive_add_properties(ot);
+}
index 96cb2d7ccc30f0e36853bf6cf73f1165cb92c791..62eb9cc240ad445fbe8360e561aa27550c97452d 100644 (file)
@@ -363,6 +363,40 @@ void ED_mask_pixelspace_factor(ScrArea *sa, ARegion *ar, float *scalex, float *s
        }
 }
 
+void ED_mask_cursor_location_get(ScrArea *sa, float cursor[2])
+{
+       if (sa) {
+               switch (sa->spacetype) {
+                       case SPACE_CLIP:
+                       {
+                               SpaceClip *space_clip = sa->spacedata.first;
+                               copy_v2_v2(cursor, space_clip->cursor);
+                               break;
+                       }
+                       case SPACE_SEQ:
+                       {
+                               zero_v2(cursor);
+                               break;
+                       }
+                       case SPACE_IMAGE:
+                       {
+                               SpaceImage *space_image = sa->spacedata.first;
+                               copy_v2_v2(cursor, space_image->cursor);
+                               break;
+                       }
+                       default:
+                               /* possible other spaces from which mask editing is available */
+                               BLI_assert(0);
+                               zero_v2(cursor);
+                               break;
+               }
+       }
+       else {
+               BLI_assert(0);
+               zero_v2(cursor);
+       }
+}
+
 /********************** registration *********************/
 
 void ED_operatortypes_mask(void)
@@ -376,6 +410,8 @@ void ED_operatortypes_mask(void)
        /* add */
        WM_operatortype_append(MASK_OT_add_vertex);
        WM_operatortype_append(MASK_OT_add_feather_vertex);
+       WM_operatortype_append(MASK_OT_primitive_circle_add);
+       WM_operatortype_append(MASK_OT_primitive_square_add);
 
        /* geometry */
        WM_operatortype_append(MASK_OT_switch_direction);
@@ -432,6 +468,9 @@ void ED_keymap_mask(wmKeyConfig *keyconf)
 
        WM_keymap_add_item(keymap, "MASK_OT_new", NKEY, KM_PRESS, KM_ALT, 0);
 
+       /* add menu */
+       WM_keymap_add_menu(keymap, "MASK_MT_add", AKEY, KM_PRESS, KM_SHIFT, 0);
+
        /* mask mode supports PET now */
        ED_keymap_proportional_cycle(keyconf, keymap);
        ED_keymap_proportional_maskmode(keyconf, keymap);
index 9374d9706963207f1b3ade1f0acc24e03e2fe1ac..51705aa5837b20867be1b66925122fa93bdde0e3 100644 (file)
@@ -42,9 +42,12 @@ struct wmOperatorType;
 /* mask_add.c */
 void MASK_OT_add_vertex(struct wmOperatorType *ot);
 void MASK_OT_add_feather_vertex(struct wmOperatorType *ot);
+void MASK_OT_primitive_circle_add(struct wmOperatorType *ot);
+void MASK_OT_primitive_square_add(struct wmOperatorType *ot);
 
 /* mask_ops.c */
 struct Mask *ED_mask_new(struct bContext *C, const char *name);
+struct MaskLayer *ED_mask_layer_ensure(struct bContext *C);
 
 void MASK_OT_new(struct wmOperatorType *ot);
 void MASK_OT_layer_new(struct wmOperatorType *ot);
index 3ae7fd67d8a58136c8501d6289ac2df0797855da..5ca0d133b0e27a8a3a63aa51d3498347a73becef 100644 (file)
@@ -292,6 +292,26 @@ Mask *ED_mask_new(bContext *C, const char *name)
        return mask;
 }
 
+/* Get ative layer. Will create mask/layer to be sure there's an active layer.  */
+MaskLayer *ED_mask_layer_ensure(bContext *C)
+{
+       Mask *mask = CTX_data_edit_mask(C);
+       MaskLayer *mask_layer;
+
+       if (mask == NULL) {
+               /* If there's no active mask, create one. */
+               mask = ED_mask_new(C, NULL);
+       }
+
+       mask_layer = BKE_mask_layer_active(mask);
+       if (mask_layer == NULL) {
+               /* If there's no active mask layer, create one. */
+               mask_layer = BKE_mask_layer_new(mask, "");
+       }
+
+       return mask_layer;
+}
+
 static int mask_new_exec(bContext *C, wmOperator *op)
 {
        char name[MAX_ID_NAME - 2];
index 73b88bcbe05546504e5a64c312b0a7ba0d9ace10..a28b75489eb3ea1d61a526efbda42714195a4f1b 100644 (file)
@@ -1004,17 +1004,6 @@ static void draw_marker_texts(SpaceClip *sc, MovieTrackingTrack *track, MovieTra
        }
 }
 
-static void view2d_to_region_float(View2D *v2d, float x, float y, float *regionx, float *regiony)
-{
-       /* express given coordinates as proportional values */
-       x = -v2d->cur.xmin / BLI_rctf_size_x(&v2d->cur);
-       y = -v2d->cur.ymin / BLI_rctf_size_y(&v2d->cur);
-
-       /* convert proportional distances to screen coordinates */
-       *regionx = v2d->mask.xmin + x * BLI_rcti_size_x(&v2d->mask);
-       *regiony = v2d->mask.ymin + y * BLI_rcti_size_y(&v2d->mask);
-}
-
 static void plane_track_colors(bool is_active, float color[3], float selected_color[3])
 {
        UI_GetThemeColor3fv(TH_MARKER, color);
@@ -1175,7 +1164,7 @@ static void draw_tracking_tracks(SpaceClip *sc, ARegion *ar, MovieClip *clip,
         * to avoid this flickering, calculate base point in the same way as it happens
         * in UI_view2d_to_region_no_clip, but do it in floats here */
 
-       view2d_to_region_float(&ar->v2d, 0.0f, 0.0f, &x, &y);
+       UI_view2d_to_region_float(&ar->v2d, 0.0f, 0.0f, &x, &y);
 
        glPushMatrix();
        glTranslatef(x, y, 0);
@@ -1418,7 +1407,7 @@ static void draw_distortion(SpaceClip *sc, ARegion *ar, MovieClip *clip,
        if ((sc->flag & SC_SHOW_GRID) == 0 && (sc->flag & SC_MANUAL_CALIBRATION) == 0)
                return;
 
-       view2d_to_region_float(&ar->v2d, 0.0f, 0.0f, &x, &y);
+       UI_view2d_to_region_float(&ar->v2d, 0.0f, 0.0f, &x, &y);
 
        glPushMatrix();
        glTranslatef(x, y, 0);
index 8d112b7413c432180e893c005e3d6f3243f0b6df..e6f1813b3a4b3acef5c72f8c8ebaf6da8f284113 100644 (file)
@@ -112,6 +112,8 @@ void CLIP_OT_prefetch(struct wmOperatorType *ot);
 
 void CLIP_OT_set_scene_frames(wmOperatorType *ot);
 
+void CLIP_OT_cursor_set(struct wmOperatorType *ot);
+
 /* clip_toolbar.c */
 struct ARegion *ED_clip_has_properties_region(struct ScrArea *sa);
 void CLIP_OT_tools(struct wmOperatorType *ot);
index c6f8cf2466a3819f5fb5ade16157b87abf418fb8..bed230a342cac443a155a0d447394be52bbc156e 100644 (file)
@@ -1458,6 +1458,51 @@ void CLIP_OT_set_scene_frames(wmOperatorType *ot)
        ot->exec = clip_set_scene_frames_exec;
 }
 
+/******************** set 3d cursor operator ********************/
+
+static int clip_set_2d_cursor_exec(bContext *C, wmOperator *op)
+{
+       SpaceClip *sclip = CTX_wm_space_clip(C);
+
+       RNA_float_get_array(op->ptr, "location", sclip->cursor);
+
+       WM_event_add_notifier(C, NC_SPACE | ND_SPACE_CLIP, NULL);
+
+       return OPERATOR_FINISHED;
+}
+
+static int clip_set_2d_cursor_invoke(bContext *C, wmOperator *op, const wmEvent *event)
+{
+       ARegion *ar = CTX_wm_region(C);
+       SpaceClip *sclip = CTX_wm_space_clip(C);
+       float location[2];
+
+       ED_clip_mouse_pos(sclip, ar, event->mval, location);
+       RNA_float_set_array(op->ptr, "location", location);
+
+       return clip_set_2d_cursor_exec(C, op);
+}
+
+void CLIP_OT_cursor_set(wmOperatorType *ot)
+{
+       /* identifiers */
+       ot->name = "Set 2D Cursor";
+       ot->description = "Set 2D cursor location";
+       ot->idname = "CLIP_OT_cursor_set";
+
+       /* api callbacks */
+       ot->exec = clip_set_2d_cursor_exec;
+       ot->invoke = clip_set_2d_cursor_invoke;
+       ot->poll = ED_space_clip_maskedit_mask_poll;
+
+       /* flags */
+       ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+
+       /* properties */
+       RNA_def_float_vector(ot->srna, "location", 2, NULL, -FLT_MAX, FLT_MAX, "Location",
+                            "Cursor location in normalized clip coordinates", -10.0f, 10.0f);
+}
+
 /********************** macroses *********************/
 
 void ED_operatormacros_clip(void)
index 8213853c9374b337a77419eb097d26401d05de56..a9bbd3481355a6e155c8387c4707d0f8aa2175cf 100644 (file)
@@ -56,6 +56,7 @@
 #include "ED_screen.h"
 #include "ED_clip.h"
 #include "ED_transform.h"
+#include "ED_uvedit.h"  /* just for draw_image_cursor */
 
 #include "IMB_imbuf.h"
 
@@ -442,6 +443,7 @@ static void clip_operatortypes(void)
        WM_operatortype_append(CLIP_OT_view_ndof);
        WM_operatortype_append(CLIP_OT_prefetch);
        WM_operatortype_append(CLIP_OT_set_scene_frames);
+       WM_operatortype_append(CLIP_OT_cursor_set);
 
        /* ** clip_toolbar.c ** */
        WM_operatortype_append(CLIP_OT_tools);
@@ -724,6 +726,9 @@ static void clip_keymap(struct wmKeyConfig *keyconf)
        RNA_enum_set(kmi->ptr, "action", TRACK_CLEAR_ALL);
        RNA_boolean_set(kmi->ptr, "clear_active", FALSE);
 
+       /* Cursor */
+       WM_keymap_add_item(keymap, "CLIP_OT_cursor_set", ACTIONMOUSE, KM_PRESS, 0, 0);
+
        /* ******** Hotkeys avalaible for preview region only ******** */
 
        keymap = WM_keymap_find(keyconf, "Clip Graph Editor", SPACE_CLIP, 0);
@@ -1153,8 +1158,9 @@ static void clip_main_area_draw(const bContext *C, ARegion *ar)
                if (mask) {
                        ScrArea *sa = CTX_wm_area(C);
                        int width, height;
-                       float aspx, aspy;
+                       float aspx, aspy, zoomx, zoomy, x, y;
                        ED_mask_get_size(sa, &width, &height);
+                       ED_space_clip_get_zoom(sc, ar, &zoomx, &zoomy);
                        ED_space_clip_get_aspect(sc, &aspx, &aspy);
                        ED_mask_draw_region(mask, ar,
                                            sc->mask_info.draw_flag, sc->mask_info.draw_type,
@@ -1162,9 +1168,18 @@ static void clip_main_area_draw(const bContext *C, ARegion *ar)
                                            aspx, aspy,
                                            TRUE, TRUE,
                                            sc->stabmat, C);
-               }
 
+                       /* TODO(sergey): would be nice to find a way to de-duplicate all this space conversions */
+                       UI_view2d_to_region_float(&ar->v2d, 0.0f, 0.0f, &x, &y);
 
+                       glPushMatrix();
+                       glTranslatef(x, y, 0);
+                       glScalef(zoomx, zoomy, 0);
+                       glMultMatrixf(sc->stabmat);
+                       glScalef(width, height, 0);
+                       draw_image_cursor(ar, sc->cursor);
+                       glPopMatrix();
+               }
        }
 
        if (sc->flag & SC_SHOW_GPENCIL) {
index 693da62c2bee70cbb85145eaaad3b1054635e753..5a8292abcaba7df4be157bea21570488c0fcd37f 100644 (file)
@@ -674,7 +674,7 @@ static void image_main_area_draw(const bContext *C, ARegion *ar)
        }
        else if (sima->mode == SI_MODE_MASK) {
                mask = ED_space_image_get_mask(sima);
-               draw_image_cursor(sima, ar);
+               draw_image_cursor(ar, sima->cursor);
        }
 
        ED_region_draw_cb_draw(C, ar, REGION_DRAW_POST_VIEW);
@@ -723,7 +723,7 @@ static void image_main_area_draw(const bContext *C, ARegion *ar)
 
                ED_mask_draw_frames(mask, ar, CFRA, mask->sfra, mask->efra);
 
-               draw_image_cursor(sima, ar);
+               draw_image_cursor(ar, sima->cursor);
        }
 
        /* scrollers? */
index a873702b5b8de19b8ec09894d0f9348288cb5d34..1ae1d57b77c20d7e7856a98b0065da8ba9f2f481 100644 (file)
@@ -69,7 +69,7 @@
 #define USE_EDBM_LOOPTRIS
 
 
-void draw_image_cursor(SpaceImage *sima, ARegion *ar)
+void draw_image_cursor(ARegion *ar, const float cursor[2])
 {
        float zoom[2], x_fac, y_fac;
 
@@ -80,7 +80,7 @@ void draw_image_cursor(SpaceImage *sima, ARegion *ar)
        y_fac = zoom[1];
        
        cpack(0xFFFFFF);
-       glTranslatef(sima->cursor[0], sima->cursor[1], 0.0);
+       glTranslatef(cursor[0], cursor[1], 0.0);
        fdrawline(-0.05f * x_fac, 0, 0, 0.05f * y_fac);
        fdrawline(0, 0.05f * y_fac, 0.05f * x_fac, 0.0f);
        fdrawline(0.05f * x_fac, 0.0f, 0.0f, -0.05f * y_fac);
@@ -108,7 +108,7 @@ void draw_image_cursor(SpaceImage *sima, ARegion *ar)
        fdrawline(0.0f, -0.020f * y_fac, 0.0f, -0.1f * y_fac);
        fdrawline(0.0f, 0.1f * y_fac, 0.0f, 0.020f * y_fac);
 
-       glTranslatef(-sima->cursor[0], -sima->cursor[1], 0.0);
+       glTranslatef(-cursor[0], -cursor[1], 0.0);
        setlinestyle(0);
 }
 
@@ -884,7 +884,7 @@ void draw_uvedit_main(SpaceImage *sima, ARegion *ar, Scene *scene, Object *obedi
                        draw_uvs_texpaint(sima, scene, obact);
 
                if (show_uvedit && !(toolsettings->use_uv_sculpt))
-                       draw_image_cursor(sima, ar);
+                       draw_image_cursor(ar, sima->cursor);
        }
 }
 
index 0b514e3f6fd00c3853f87712066ba0738426ce69..8c299cccbc2b75e2b78bd921779ecb49958106b2 100644 (file)
@@ -3823,6 +3823,12 @@ static void UV_OT_reveal(wmOperatorType *ot)
 
 /******************** set 3d cursor operator ********************/
 
+static int uv_set_2d_cursor_poll(bContext *C)
+{
+       return ED_operator_uvedit_space_image(C) ||
+              ED_space_image_maskedit_poll(C);
+}
+
 static int uv_set_2d_cursor_exec(bContext *C, wmOperator *op)
 {
        SpaceImage *sima = CTX_wm_space_image(C);
@@ -3858,7 +3864,7 @@ static void UV_OT_cursor_set(wmOperatorType *ot)
        /* api callbacks */
        ot->exec = uv_set_2d_cursor_exec;
        ot->invoke = uv_set_2d_cursor_invoke;
-       ot->poll = ED_operator_uvedit_space_image;
+       ot->poll = uv_set_2d_cursor_poll;
 
        /* flags */
        ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
index e8e5a01ca84ee5996ded3638667eb3241ab307b4..0478ff567a0ced58fb4b3b841e3e489ab3a9f37f 100644 (file)
@@ -1093,6 +1093,8 @@ typedef struct SpaceClip {
 
        int around, pad4;             /* pivot point for transforms */
 
+       float cursor[2];              /* Mask editor 2d cursor */
+
        MaskSpaceInfo mask_info;
 } SpaceClip;