Fix #19382: crash on uv edit stitch, tweaking limit property in tool area.
[blender-staging.git] / source / blender / editors / uvedit / uvedit_ops.c
index a42008bef0c38a1a21c2b16dda31f7ce09d35812..9216cfb5cdc96bdcf0afff545517a3d162d4a99b 100644 (file)
 #include "BKE_report.h"
 #include "BKE_utildefines.h"
 
-#include "BIF_transform.h"
-
 #include "ED_image.h"
 #include "ED_mesh.h"
 #include "ED_screen.h"
+#include "ED_transform.h"
 
 #include "RNA_access.h"
 #include "RNA_define.h"
@@ -78,7 +77,7 @@ int ED_uvedit_test(Object *obedit)
        EditMesh *em;
        int ret;
 
-       if(obedit->type != OB_MESH)
+       if(!obedit || obedit->type != OB_MESH)
                return 0;
 
        em = BKE_mesh_get_editmesh(obedit->data);
@@ -126,9 +125,6 @@ void ED_uvedit_assign_image(Scene *scene, Object *obedit, Image *ima, Image *pre
                                tf->tpage= ima;
                                tf->mode |= TF_TEX;
                                
-                               if(ima->tpageflag & IMA_TILES) tf->mode |= TF_TILES;
-                               else tf->mode &= ~TF_TILES;
-                               
                                if(ima->id.us==0) id_us_plus(&ima->id);
                                else id_lib_extern(&ima->id);
                        }
@@ -143,14 +139,14 @@ void ED_uvedit_assign_image(Scene *scene, Object *obedit, Image *ima, Image *pre
 
        /* and update depdency graph */
        if(update)
-               DAG_object_flush_update(scene, obedit, OB_RECALC_DATA);
+               DAG_id_flush_update(obedit->data, OB_RECALC_DATA);
 
        BKE_mesh_end_editmesh(obedit->data, em);
 }
 
 /* dotile -    1, set the tile flag (from the space image)
  *                     2, set the tile index for the faces. */
-void ED_uvedit_set_tile(bContext *C, Scene *scene, Object *obedit, Image *ima, int curtile, int dotile)
+void ED_uvedit_set_tile(bContext *C, Scene *scene, Object *obedit, Image *ima, int curtile)
 {
        EditMesh *em;
        EditFace *efa;
@@ -169,21 +165,12 @@ void ED_uvedit_set_tile(bContext *C, Scene *scene, Object *obedit, Image *ima, i
        for(efa= em->faces.first; efa; efa= efa->next) {
                tf = CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
 
-               if(efa->h==0 && efa->f & SELECT) {
-                       if(dotile==1) {
-                               /* set tile flag */
-                               if(ima->tpageflag & IMA_TILES)
-                                       tf->mode |= TF_TILES;
-                               else
-                                       tf->mode &= ~TF_TILES;
-                       }
-                       else if(dotile==2)
-                               tf->tile= curtile; /* set tile index */
-               }
+               if(efa->h==0 && efa->f & SELECT)
+                       tf->tile= curtile; /* set tile index */
        }
 
-       DAG_object_flush_update(scene, obedit, OB_RECALC_DATA);
-       WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_DATA, obedit);
+       DAG_id_flush_update(obedit->data, OB_RECALC_DATA);
+       WM_event_add_notifier(C, NC_GEOM|ND_DATA, obedit->data);
        BKE_mesh_end_editmesh(obedit->data, em);
 }
 
@@ -193,7 +180,13 @@ static void uvedit_pixel_to_float(SpaceImage *sima, float *dist, float pixeldist
 {
        int width, height;
 
-       ED_space_image_size(sima, &width, &height);
+       if(sima) {
+               ED_space_image_size(sima, &width, &height);
+       }
+       else {
+               width= 256;
+               height= 256;
+       }
 
        dist[0]= pixeldist/width;
        dist[1]= pixeldist/height;
@@ -203,7 +196,9 @@ static void uvedit_pixel_to_float(SpaceImage *sima, float *dist, float pixeldist
 
 int uvedit_face_visible_nolocal(Scene *scene, EditFace *efa)
 {
-       if(scene->toolsettings->uv_flag & UV_SYNC_SELECTION)
+       ToolSettings *ts= scene->toolsettings;
+
+       if(ts->uv_flag & UV_SYNC_SELECTION)
                return (efa->h==0);
        else
                return (efa->h==0 && (efa->f & SELECT));
@@ -211,7 +206,9 @@ int uvedit_face_visible_nolocal(Scene *scene, EditFace *efa)
 
 int uvedit_face_visible(Scene *scene, Image *ima, EditFace *efa, MTFace *tf)
 {
-       if(scene->toolsettings->uv_flag & UV_SHOW_SAME_IMAGE)
+       ToolSettings *ts= scene->toolsettings;
+
+       if(ts->uv_flag & UV_SHOW_SAME_IMAGE)
                return (tf->tpage==ima)? uvedit_face_visible_nolocal(scene, efa): 0;
        else
                return uvedit_face_visible_nolocal(scene, efa);
@@ -219,7 +216,9 @@ int uvedit_face_visible(Scene *scene, Image *ima, EditFace *efa, MTFace *tf)
 
 int uvedit_face_selected(Scene *scene, EditFace *efa, MTFace *tf)
 {
-       if(scene->toolsettings->uv_flag & UV_SYNC_SELECTION)
+       ToolSettings *ts= scene->toolsettings;
+
+       if(ts->uv_flag & UV_SYNC_SELECTION)
                return (efa->f & SELECT);
        else
                return (!(~tf->flag & (TF_SEL1|TF_SEL2|TF_SEL3)) &&(!efa->v4 || tf->flag & TF_SEL4));
@@ -227,7 +226,9 @@ int uvedit_face_selected(Scene *scene, EditFace *efa, MTFace *tf)
 
 void uvedit_face_select(Scene *scene, EditFace *efa, MTFace *tf)
 {
-       if(scene->toolsettings->uv_flag & UV_SYNC_SELECTION)
+       ToolSettings *ts= scene->toolsettings;
+
+       if(ts->uv_flag & UV_SYNC_SELECTION)
                EM_select_face(efa, 1);
        else
                tf->flag |= (TF_SEL1|TF_SEL2|TF_SEL3|TF_SEL4);
@@ -235,7 +236,9 @@ void uvedit_face_select(Scene *scene, EditFace *efa, MTFace *tf)
 
 void uvedit_face_deselect(Scene *scene, EditFace *efa, MTFace *tf)
 {
-       if(scene->toolsettings->uv_flag & UV_SYNC_SELECTION)
+       ToolSettings *ts= scene->toolsettings;
+
+       if(ts->uv_flag & UV_SYNC_SELECTION)
                EM_select_face(efa, 0);
        else
                tf->flag &= ~(TF_SEL1|TF_SEL2|TF_SEL3|TF_SEL4);
@@ -243,12 +246,13 @@ void uvedit_face_deselect(Scene *scene, EditFace *efa, MTFace *tf)
 
 int uvedit_edge_selected(Scene *scene, EditFace *efa, MTFace *tf, int i)
 {
+       ToolSettings *ts= scene->toolsettings;
        int nvert= (efa->v4)? 4: 3;
 
-       if(scene->toolsettings->uv_flag & UV_SYNC_SELECTION) {
-               if(scene->selectmode == SCE_SELECT_FACE)
+       if(ts->uv_flag & UV_SYNC_SELECTION) {
+               if(ts->selectmode == SCE_SELECT_FACE)
                        return (efa->f & SELECT);
-               else if(scene->selectmode == SCE_SELECT_EDGE)
+               else if(ts->selectmode == SCE_SELECT_EDGE)
                        return (*(&efa->e1 + i))->f & SELECT;
                else
                        return (((efa->v1 + i)->f & SELECT) && ((efa->v1 + (i+1)%nvert)->f & SELECT));
@@ -259,12 +263,13 @@ int uvedit_edge_selected(Scene *scene, EditFace *efa, MTFace *tf, int i)
 
 void uvedit_edge_select(Scene *scene, EditFace *efa, MTFace *tf, int i)
 {
+       ToolSettings *ts= scene->toolsettings;
        int nvert= (efa->v4)? 4: 3;
 
-       if(scene->toolsettings->uv_flag & UV_SYNC_SELECTION) {
-               if(scene->selectmode == SCE_SELECT_FACE)
+       if(ts->uv_flag & UV_SYNC_SELECTION) {
+               if(ts->selectmode == SCE_SELECT_FACE)
                        EM_select_face(efa, 1);
-               else if(scene->selectmode == SCE_SELECT_EDGE)
+               else if(ts->selectmode == SCE_SELECT_EDGE)
                        EM_select_edge((*(&efa->e1 + i)), 1);
                else {
                        (efa->v1 + i)->f |= SELECT;
@@ -277,12 +282,13 @@ void uvedit_edge_select(Scene *scene, EditFace *efa, MTFace *tf, int i)
 
 void uvedit_edge_deselect(Scene *scene, EditFace *efa, MTFace *tf, int i)
 {
+       ToolSettings *ts= scene->toolsettings;
        int nvert= (efa->v4)? 4: 3;
 
-       if(scene->toolsettings->uv_flag & UV_SYNC_SELECTION) {
-               if(scene->selectmode == SCE_SELECT_FACE)
+       if(ts->uv_flag & UV_SYNC_SELECTION) {
+               if(ts->selectmode == SCE_SELECT_FACE)
                        EM_select_face(efa, 0);
-               else if(scene->selectmode == SCE_SELECT_EDGE)
+               else if(ts->selectmode == SCE_SELECT_EDGE)
                        EM_select_edge((*(&efa->e1 + i)), 0);
                else {
                        (efa->v1 + i)->f &= ~SELECT;
@@ -295,8 +301,10 @@ void uvedit_edge_deselect(Scene *scene, EditFace *efa, MTFace *tf, int i)
 
 int uvedit_uv_selected(Scene *scene, EditFace *efa, MTFace *tf, int i)
 {
-       if(scene->toolsettings->uv_flag & UV_SYNC_SELECTION) {
-               if(scene->selectmode == SCE_SELECT_FACE)
+       ToolSettings *ts= scene->toolsettings;
+
+       if(ts->uv_flag & UV_SYNC_SELECTION) {
+               if(ts->selectmode == SCE_SELECT_FACE)
                        return (efa->f & SELECT);
                else
                        return (*(&efa->v1 + i))->f & SELECT;
@@ -307,8 +315,10 @@ int uvedit_uv_selected(Scene *scene, EditFace *efa, MTFace *tf, int i)
 
 void uvedit_uv_select(Scene *scene, EditFace *efa, MTFace *tf, int i)
 {
-       if(scene->toolsettings->uv_flag & UV_SYNC_SELECTION) {
-               if(scene->selectmode == SCE_SELECT_FACE)
+       ToolSettings *ts= scene->toolsettings;
+
+       if(ts->uv_flag & UV_SYNC_SELECTION) {
+               if(ts->selectmode == SCE_SELECT_FACE)
                        EM_select_face(efa, 1);
                else
                        (*(&efa->v1 + i))->f |= SELECT;
@@ -319,8 +329,10 @@ void uvedit_uv_select(Scene *scene, EditFace *efa, MTFace *tf, int i)
 
 void uvedit_uv_deselect(Scene *scene, EditFace *efa, MTFace *tf, int i)
 {
-       if(scene->toolsettings->uv_flag & UV_SYNC_SELECTION) {
-               if(scene->selectmode == SCE_SELECT_FACE)
+       ToolSettings *ts= scene->toolsettings;
+
+       if(ts->uv_flag & UV_SYNC_SELECTION) {
+               if(ts->selectmode == SCE_SELECT_FACE)
                        EM_select_face(efa, 0);
                else
                        (*(&efa->v1 + i))->f &= ~SELECT;
@@ -936,50 +948,6 @@ static void select_linked(Scene *scene, Image *ima, EditMesh *em, float limit[2]
        EM_free_uv_vert_map(vmap);
 }
 
-/* ******************** mirror operator **************** */
-
-static int mirror_exec(bContext *C, wmOperator *op)
-{
-       float mat[3][3];
-       int axis;
-       
-       Mat3One(mat);
-       axis= RNA_enum_get(op->ptr, "axis");
-
-       if(axis == 'x') {
-               /* XXX initTransform(TFM_MIRROR, CTX_NO_PET|CTX_AUTOCONFIRM);
-               BIF_setSingleAxisConstraint(mat[0], " on X axis");
-               Transform(); */
-       }
-       else {
-               /* XXX initTransform(TFM_MIRROR, CTX_NO_PET|CTX_AUTOCONFIRM);
-               BIF_setSingleAxisConstraint(mat[1], " on Y axis");
-               Transform(); */
-       }
-
-       return OPERATOR_FINISHED;
-}
-
-void UV_OT_mirror(wmOperatorType *ot)
-{
-       static EnumPropertyItem axis_items[] = {
-               {'x', "MIRROR_X", 0, "Mirror X", "Mirror UVs over X axis."},
-               {'y', "MIRROR_Y", 0, "Mirror Y", "Mirror UVs over Y axis."},
-               {0, NULL, 0, NULL, NULL}};
-
-       /* identifiers */
-       ot->name= "Mirror";
-       ot->idname= "UV_OT_mirror";
-       ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
-       
-       /* api callbacks */
-       ot->exec= mirror_exec;
-       ot->poll= ED_operator_uvedit;
-
-       /* properties */
-       RNA_def_enum(ot->srna, "axis", axis_items, 'x', "Axis", "Axis to mirror UV locations over.");
-}
-
 /* ******************** align operator **************** */
 
 static void weld_align_uv(bContext *C, int tool)
@@ -1052,8 +1020,8 @@ static void weld_align_uv(bContext *C, int tool)
                }
        }
 
-       DAG_object_flush_update(scene, obedit, OB_RECALC_DATA);
-       WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_DATA, obedit);
+       DAG_id_flush_update(obedit->data, OB_RECALC_DATA);
+       WM_event_add_notifier(C, NC_GEOM|ND_DATA, obedit->data);
 
        BKE_mesh_end_editmesh(obedit->data, em);
 }
@@ -1126,7 +1094,7 @@ static int stitch_exec(bContext *C, wmOperator *op)
        Image *ima;
        MTFace *tf;
        
-       sima= (SpaceImage*)CTX_wm_space_data(C);
+       sima= CTX_wm_space_image(C);
        scene= CTX_data_scene(C);
        obedit= CTX_data_edit_object(C);
        em= BKE_mesh_get_editmesh((Mesh*)obedit->data);
@@ -1135,11 +1103,11 @@ static int stitch_exec(bContext *C, wmOperator *op)
        if(RNA_boolean_get(op->ptr, "use_limit")) {
                UvVertMap *vmap;
                UvMapVert *vlist, *iterv;
-               float newuv[2], limit[2], pixels;
+               float newuv[2], limit[2];
                int a, vtot;
 
-               pixels= RNA_float_get(op->ptr, "limit");
-               uvedit_pixel_to_float(sima, limit, pixels);
+               limit[0]= RNA_float_get(op->ptr, "limit");
+               limit[1]= limit[0];
 
                EM_init_index_arrays(em, 0, 0, 1);
                vmap= EM_make_uv_vert_map(em, 1, 0, limit);
@@ -1273,8 +1241,8 @@ static int stitch_exec(bContext *C, wmOperator *op)
                MEM_freeN(uv_average);
        }
 
-       DAG_object_flush_update(scene, obedit, OB_RECALC_DATA);
-       WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_DATA, obedit);
+       DAG_id_flush_update(obedit->data, OB_RECALC_DATA);
+       WM_event_add_notifier(C, NC_GEOM|ND_DATA, obedit->data);
 
        BKE_mesh_end_editmesh(obedit->data, em);
        return OPERATOR_FINISHED;
@@ -1293,7 +1261,7 @@ void UV_OT_stitch(wmOperatorType *ot)
 
        /* properties */
        RNA_def_boolean(ot->srna, "use_limit", 1, "Use Limit", "Stitch UVs within a specified limit distance.");
-       RNA_def_float(ot->srna, "limit", 20.0, 0.0f, FLT_MAX, "Limit", "Limit distance in image pixels.", -FLT_MAX, FLT_MAX);
+       RNA_def_float(ot->srna, "limit", 0.01f, 0.0f, FLT_MAX, "Limit", "Limit distance in normalized coordinates.", -FLT_MAX, FLT_MAX);
 }
 
 /* ******************** (de)select all operator **************** */
@@ -1301,6 +1269,7 @@ void UV_OT_stitch(wmOperatorType *ot)
 static int select_inverse_exec(bContext *C, wmOperator *op)
 {
        Scene *scene;
+       ToolSettings *ts;
        Object *obedit;
        EditMesh *em;
        EditFace *efa;
@@ -1308,11 +1277,12 @@ static int select_inverse_exec(bContext *C, wmOperator *op)
        MTFace *tf;
        
        scene= CTX_data_scene(C);
+       ts= CTX_data_tool_settings(C);
        obedit= CTX_data_edit_object(C);
        em= BKE_mesh_get_editmesh((Mesh*)obedit->data);
        ima= CTX_data_edit_image(C);
 
-       if(scene->toolsettings->uv_flag & UV_SYNC_SELECTION) {
+       if(ts->uv_flag & UV_SYNC_SELECTION) {
                EM_select_swap(em);
        }
        else {
@@ -1328,17 +1298,17 @@ static int select_inverse_exec(bContext *C, wmOperator *op)
                }
        }
 
-       WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit);
+       WM_event_add_notifier(C, NC_GEOM|ND_DATA, obedit->data);
 
        BKE_mesh_end_editmesh(obedit->data, em);
        return OPERATOR_FINISHED;
 }
 
-void UV_OT_select_invert(wmOperatorType *ot)
+void UV_OT_select_inverse(wmOperatorType *ot)
 {
        /* identifiers */
-       ot->name= "Select Invert";
-       ot->idname= "UV_OT_select_invert";
+       ot->name= "Select Inverse";
+       ot->idname= "UV_OT_select_inverse";
        ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
        
        /* api callbacks */
@@ -1351,6 +1321,7 @@ void UV_OT_select_invert(wmOperatorType *ot)
 static int de_select_all_exec(bContext *C, wmOperator *op)
 {
        Scene *scene;
+       ToolSettings *ts;
        Object *obedit;
        EditMesh *em;
        EditFace *efa;
@@ -1359,11 +1330,12 @@ static int de_select_all_exec(bContext *C, wmOperator *op)
        int sel;
        
        scene= CTX_data_scene(C);
+       ts= CTX_data_tool_settings(C);
        obedit= CTX_data_edit_object(C);
        em= BKE_mesh_get_editmesh((Mesh*)obedit->data);
        ima= CTX_data_edit_image(C);
        
-       if(scene->toolsettings->uv_flag & UV_SYNC_SELECTION) {
+       if(ts->uv_flag & UV_SYNC_SELECTION) {
                EM_toggle_select_all(em);
        }
        else {
@@ -1396,7 +1368,7 @@ static int de_select_all_exec(bContext *C, wmOperator *op)
                }
        }
 
-       WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit);
+       WM_event_add_notifier(C, NC_GEOM|ND_SELECT, obedit->data);
 
        BKE_mesh_end_editmesh(obedit->data, em);
        return OPERATOR_FINISHED;
@@ -1441,8 +1413,9 @@ static int sticky_select(float *limit, int hitv[4], int v, float *hituv[4], floa
 
 static int mouse_select(bContext *C, float co[2], int extend, int loop)
 {
-       SpaceImage *sima= (SpaceImage*)CTX_wm_space_data(C);
+       SpaceImage *sima= CTX_wm_space_image(C);
        Scene *scene= CTX_data_scene(C);
+       ToolSettings *ts= CTX_data_tool_settings(C);
        Object *obedit= CTX_data_edit_object(C);
        Image *ima= CTX_data_edit_image(C);
        EditMesh *em= BKE_mesh_get_editmesh((Mesh*)obedit->data);
@@ -1457,12 +1430,12 @@ static int mouse_select(bContext *C, float co[2], int extend, int loop)
        uvedit_pixel_to_float(sima, penalty, 5.0f);
 
        /* retrieve operation mode */
-       if(scene->toolsettings->uv_flag & UV_SYNC_SELECTION) {
+       if(ts->uv_flag & UV_SYNC_SELECTION) {
                sync= 1;
 
-               if(scene->selectmode & SCE_SELECT_FACE)
+               if(ts->selectmode & SCE_SELECT_FACE)
                        selectmode= UV_SELECT_FACE;
-               else if(scene->selectmode & SCE_SELECT_EDGE)
+               else if(ts->selectmode & SCE_SELECT_EDGE)
                        selectmode= UV_SELECT_EDGE;
                else
                        selectmode= UV_SELECT_VERTEX;
@@ -1471,8 +1444,8 @@ static int mouse_select(bContext *C, float co[2], int extend, int loop)
        }
        else {
                sync= 0;
-               selectmode= scene->toolsettings->uv_selectmode;
-               sticky= sima->sticky;
+               selectmode= ts->uv_selectmode;
+               sticky= (sima)? sima->sticky: 1;
        }
 
        /* find nearest element */
@@ -1693,14 +1666,14 @@ static int mouse_select(bContext *C, float co[2], int extend, int loop)
        
        if(sync) {
                /* flush for mesh selection */
-               if(scene->selectmode != SCE_SELECT_FACE) {
+               if(ts->selectmode != SCE_SELECT_FACE) {
                        if(flush==1)            EM_select_flush(em);
                        else if(flush==-1)      EM_deselect_flush(em);
                }
        }
        
-       DAG_object_flush_update(scene, obedit, OB_RECALC_DATA);
-       WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit);
+       DAG_id_flush_update(obedit->data, OB_RECALC_DATA);
+       WM_event_add_notifier(C, NC_GEOM|ND_SELECT, obedit->data);
        
        BKE_mesh_end_editmesh(obedit->data, em);
        return OPERATOR_PASS_THROUGH|OPERATOR_FINISHED;
@@ -1804,15 +1777,16 @@ void UV_OT_select_loop(wmOperatorType *ot)
 
 static int select_linked_exec(bContext *C, wmOperator *op)
 {
-       SpaceImage *sima= (SpaceImage*)CTX_wm_space_data(C);
+       SpaceImage *sima= CTX_wm_space_image(C);
        Scene *scene= CTX_data_scene(C);
+       ToolSettings *ts= CTX_data_tool_settings(C);
        Object *obedit= CTX_data_edit_object(C);
        Image *ima= CTX_data_edit_image(C);
        EditMesh *em= BKE_mesh_get_editmesh((Mesh*)obedit->data);
        float limit[2];
        int extend;
 
-       if(scene->toolsettings->uv_flag & UV_SYNC_SELECTION) {
+       if(ts->uv_flag & UV_SYNC_SELECTION) {
                BKE_report(op->reports, RPT_ERROR, "Can't select linked when sync selection is enabled.");
                BKE_mesh_end_editmesh(obedit->data, em);
                return OPERATOR_CANCELLED;
@@ -1822,8 +1796,8 @@ static int select_linked_exec(bContext *C, wmOperator *op)
        uvedit_pixel_to_float(sima, limit, 0.05f);
        select_linked(scene, ima, em, limit, NULL, extend);
 
-       DAG_object_flush_update(scene, obedit, OB_RECALC_DATA);
-       WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit);
+       DAG_id_flush_update(obedit->data, OB_RECALC_DATA);
+       WM_event_add_notifier(C, NC_GEOM|ND_SELECT, obedit->data);
 
        BKE_mesh_end_editmesh(obedit->data, em);
        return OPERATOR_FINISHED;
@@ -1850,13 +1824,14 @@ void UV_OT_select_linked(wmOperatorType *ot)
 static int unlink_selection_exec(bContext *C, wmOperator *op)
 {
        Scene *scene= CTX_data_scene(C);
+       ToolSettings *ts= CTX_data_tool_settings(C);
        Object *obedit= CTX_data_edit_object(C);
        Image *ima= CTX_data_edit_image(C);
        EditMesh *em= BKE_mesh_get_editmesh((Mesh*)obedit->data);
        EditFace *efa;
        MTFace *tf;
 
-       if(scene->toolsettings->uv_flag & UV_SYNC_SELECTION) {
+       if(ts->uv_flag & UV_SYNC_SELECTION) {
                BKE_report(op->reports, RPT_ERROR, "Can't unlink selection when sync selection is enabled.");
                BKE_mesh_end_editmesh(obedit->data, em);
                return OPERATOR_CANCELLED;
@@ -1877,8 +1852,8 @@ static int unlink_selection_exec(bContext *C, wmOperator *op)
                }
        }
        
-       DAG_object_flush_update(scene, obedit, OB_RECALC_DATA);
-       WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit);
+       DAG_id_flush_update(obedit->data, OB_RECALC_DATA);
+       WM_event_add_notifier(C, NC_GEOM|ND_SELECT, obedit->data);
 
        BKE_mesh_end_editmesh(obedit->data, em);
        return OPERATOR_FINISHED;
@@ -1913,12 +1888,13 @@ static void uv_faces_do_sticky(bContext *C, SpaceImage *sima, Scene *scene, Obje
         * This only needs to be done when the Mesh is not used for
         * selection (so for sticky modes, vertex or location based). */
        
+       ToolSettings *ts= CTX_data_tool_settings(C);
        EditMesh *em= BKE_mesh_get_editmesh((Mesh*)obedit->data);
        EditFace *efa;
        MTFace *tf;
        int nverts, i;
        
-       if((scene->toolsettings->uv_flag & UV_SYNC_SELECTION)==0 && sima->sticky == SI_STICKY_VERTEX) {
+       if((ts->uv_flag & UV_SYNC_SELECTION)==0 && sima->sticky == SI_STICKY_VERTEX) {
                /* Tag all verts as untouched, then touch the ones that have a face center
                 * in the loop and select all MTFace UV's that use a touched vert. */
                EditVert *eve;
@@ -1949,7 +1925,7 @@ static void uv_faces_do_sticky(bContext *C, SpaceImage *sima, Scene *scene, Obje
                        }
                }
        }
-       else if((scene->toolsettings->uv_flag & UV_SYNC_SELECTION)==0 && sima->sticky == SI_STICKY_LOC) {
+       else if((ts->uv_flag & UV_SYNC_SELECTION)==0 && sima->sticky == SI_STICKY_LOC) {
                EditFace *efa_vlist;
                MTFace *tf_vlist;
                UvMapVert *start_vlist=NULL, *vlist_iter;
@@ -2020,7 +1996,7 @@ static void uv_faces_do_sticky(bContext *C, SpaceImage *sima, Scene *scene, Obje
                EM_free_uv_vert_map(vmap);
                
        }
-       else { /* SI_STICKY_DISABLE or scene->toolsettings->uv_flag & UV_SYNC_SELECTION */
+       else { /* SI_STICKY_DISABLE or ts->uv_flag & UV_SYNC_SELECTION */
                for(efa= em->faces.first; efa; efa= efa->next) {
                        if(efa->tmp.l) {
                                tf = CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
@@ -2036,8 +2012,9 @@ static void uv_faces_do_sticky(bContext *C, SpaceImage *sima, Scene *scene, Obje
 
 static int border_select_exec(bContext *C, wmOperator *op)
 {
-       SpaceImage *sima= (SpaceImage*)CTX_wm_space_data(C);
+       SpaceImage *sima= CTX_wm_space_image(C);
        Scene *scene= CTX_data_scene(C);
+       ToolSettings *ts= CTX_data_tool_settings(C);
        Object *obedit= CTX_data_edit_object(C);
        Image *ima= CTX_data_edit_image(C);
        ARegion *ar= CTX_wm_region(C);
@@ -2061,10 +2038,10 @@ static int border_select_exec(bContext *C, wmOperator *op)
        select= (RNA_int_get(op->ptr, "event_type") == LEFTMOUSE); // XXX hardcoded
        pinned= RNA_boolean_get(op->ptr, "pinned");
        
-       if(scene->toolsettings->uv_flag & UV_SYNC_SELECTION)
-               faces= (scene->selectmode == SCE_SELECT_FACE);
+       if(ts->uv_flag & UV_SYNC_SELECTION)
+               faces= (ts->selectmode == SCE_SELECT_FACE);
        else
-               faces= (scene->toolsettings->uv_selectmode == UV_SELECT_FACE);
+               faces= (ts->uv_selectmode == UV_SELECT_FACE);
 
        /* do actual selection */
        if(faces && !pinned) {
@@ -2096,7 +2073,7 @@ static int border_select_exec(bContext *C, wmOperator *op)
                for(efa= em->faces.first; efa; efa= efa->next) {
                        tface= CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
                        if(uvedit_face_visible(scene, ima, efa, tface)) {
-                               if(!pinned || (scene->toolsettings->uv_flag & UV_SYNC_SELECTION) ) {
+                               if(!pinned || (ts->uv_flag & UV_SYNC_SELECTION) ) {
                                        /* UV_SYNC_SELECTION - can't do pinned selection */
                                        if(BLI_in_rctf(&rectf, tface->uv[0][0], tface->uv[0][1])) {
                                                if(select)      uvedit_uv_select(scene, efa, tface, 0);
@@ -2145,14 +2122,14 @@ static int border_select_exec(bContext *C, wmOperator *op)
 
        if(change) {
                /* make sure newly selected vert selection is updated*/
-               if(scene->toolsettings->uv_flag & UV_SYNC_SELECTION) {
-                       if(scene->selectmode != SCE_SELECT_FACE) {
+               if(ts->uv_flag & UV_SYNC_SELECTION) {
+                       if(ts->selectmode != SCE_SELECT_FACE) {
                                if(select)      EM_select_flush(em);
                                else            EM_deselect_flush(em);
                        }
                }
 
-               WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit);
+               WM_event_add_notifier(C, NC_GEOM|ND_SELECT, obedit->data);
                
                BKE_mesh_end_editmesh(obedit->data, em);
                return OPERATOR_FINISHED;
@@ -2208,7 +2185,7 @@ static void select_uv_inside_ellipse(SpaceImage *sima, Scene *scene, int select,
 
 int circle_select_exec(bContext *C, wmOperator *op)
 {
-       SpaceImage *sima= (SpaceImage*)CTX_wm_space_data(C);
+       SpaceImage *sima= CTX_wm_space_image(C);
        Scene *scene= CTX_data_scene(C);
        Object *obedit= CTX_data_edit_object(C);
        EditMesh *em= BKE_mesh_get_editmesh((Mesh*)obedit->data);
@@ -2247,7 +2224,7 @@ int circle_select_exec(bContext *C, wmOperator *op)
        if(select) EM_select_flush(em);
        else EM_deselect_flush(em);
 
-       WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit);
+       WM_event_add_notifier(C, NC_GEOM|ND_SELECT, obedit->data);
 
        BKE_mesh_end_editmesh(obedit->data, em);
        return OPERATOR_FINISHED;
@@ -2298,7 +2275,7 @@ static int snap_cursor_to_selection(Scene *scene, Image *ima, Object *obedit, Vi
 
 static int snap_cursor_exec(bContext *C, wmOperator *op)
 {
-       SpaceImage *sima= (SpaceImage*)CTX_wm_space_data(C);
+       SpaceImage *sima= CTX_wm_space_image(C);
        Scene *scene= CTX_data_scene(C);
        Object *obedit= CTX_data_edit_object(C);
        Image *ima= CTX_data_edit_image(C);
@@ -2500,13 +2477,18 @@ static int snap_uvs_to_adjacent_unselected(Scene *scene, Image *ima, Object *obe
 static int snap_uvs_to_pixels(SpaceImage *sima, Scene *scene, Object *obedit)
 {
        EditMesh *em= BKE_mesh_get_editmesh((Mesh*)obedit->data);
-       Image *ima= sima->image;
+       Image *ima;
        EditFace *efa;
        MTFace *tface;
        int width= 0, height= 0;
        float w, h;
        short change = 0;
 
+       if(!sima)
+               return 0;
+       
+       ima= sima->image;
+       
        ED_space_image_size(sima, &width, &height);
        w = (float)width;
        h = (float)height;
@@ -2530,7 +2512,7 @@ static int snap_uvs_to_pixels(SpaceImage *sima, Scene *scene, Object *obedit)
 
 static int snap_selection_exec(bContext *C, wmOperator *op)
 {
-       SpaceImage *sima= (SpaceImage*)CTX_wm_space_data(C);
+       SpaceImage *sima= CTX_wm_space_image(C);
        Scene *scene= CTX_data_scene(C);
        Object *obedit= CTX_data_edit_object(C);
        Image *ima= CTX_data_edit_image(C);
@@ -2552,8 +2534,8 @@ static int snap_selection_exec(bContext *C, wmOperator *op)
        if(!change)
                return OPERATOR_CANCELLED;
        
-       DAG_object_flush_update(scene, obedit, OB_RECALC_DATA);
-       WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_DATA, obedit);
+       DAG_id_flush_update(obedit->data, OB_RECALC_DATA);
+       WM_event_add_notifier(C, NC_GEOM|ND_DATA, obedit->data);
 
        return OPERATOR_FINISHED;
 }
@@ -2612,7 +2594,7 @@ static int pin_exec(bContext *C, wmOperator *op)
                }
        }
        
-       WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_DATA, obedit);
+       WM_event_add_notifier(C, NC_GEOM|ND_DATA, obedit->data);
 
        BKE_mesh_end_editmesh(obedit->data, em);
        return OPERATOR_FINISHED;
@@ -2657,7 +2639,7 @@ static int select_pinned_exec(bContext *C, wmOperator *op)
                }
        }
        
-       WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit);
+       WM_event_add_notifier(C, NC_GEOM|ND_SELECT, obedit->data);
 
        BKE_mesh_end_editmesh(obedit->data, em);
        return OPERATOR_FINISHED;
@@ -2679,17 +2661,18 @@ void UV_OT_select_pinned(wmOperatorType *ot)
 
 static int hide_exec(bContext *C, wmOperator *op)
 {
-       SpaceImage *sima= (SpaceImage*)CTX_wm_space_data(C);
-       Scene *scene= CTX_data_scene(C);
+       SpaceImage *sima= CTX_wm_space_image(C);
+       ToolSettings *ts= CTX_data_tool_settings(C);
        Object *obedit= CTX_data_edit_object(C);
        EditMesh *em= BKE_mesh_get_editmesh((Mesh*)obedit->data);
        EditFace *efa;
        MTFace *tf;
        int swap= RNA_boolean_get(op->ptr, "unselected");
+       int facemode= sima ? sima->flag & SI_SELACTFACE : 0;
 
-       if(scene->toolsettings->uv_flag & UV_SYNC_SELECTION) {
+       if(ts->uv_flag & UV_SYNC_SELECTION) {
                EM_hide_mesh(em, swap);
-               WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit);
+               WM_event_add_notifier(C, NC_GEOM|ND_SELECT, obedit->data);
 
                BKE_mesh_end_editmesh(obedit->data, em);
                return OPERATOR_FINISHED;
@@ -2699,7 +2682,7 @@ static int hide_exec(bContext *C, wmOperator *op)
                for(efa= em->faces.first; efa; efa= efa->next) {
                        if(efa->f & SELECT) {
                                tf= CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
-                               if(sima->flag & SI_SELACTFACE) {
+                               if(facemode) {
                                        /* Pretend face mode */
                                        if((    (efa->v4==NULL && 
                                                        (       tf->flag & (TF_SEL1|TF_SEL2|TF_SEL3)) ==                        (TF_SEL1|TF_SEL2|TF_SEL3) )                      ||
@@ -2744,7 +2727,7 @@ static int hide_exec(bContext *C, wmOperator *op)
                        if(efa->f & SELECT) {
                                tf= CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
 
-                               if(sima->flag & SI_SELACTFACE) {
+                               if(facemode) {
                                        if(     (efa->v4==NULL && 
                                                        (       tf->flag & (TF_SEL1|TF_SEL2|TF_SEL3)) ==                        (TF_SEL1|TF_SEL2|TF_SEL3) )                      ||
                                                        (       tf->flag & (TF_SEL1|TF_SEL2|TF_SEL3|TF_SEL4)) ==        (TF_SEL1|TF_SEL2|TF_SEL3|TF_SEL4)       ) {
@@ -2797,7 +2780,7 @@ static int hide_exec(bContext *C, wmOperator *op)
        }
        
        EM_validate_selections(em);
-       WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit);
+       WM_event_add_notifier(C, NC_GEOM|ND_SELECT, obedit->data);
 
        BKE_mesh_end_editmesh(obedit->data, em);
        return OPERATOR_FINISHED;
@@ -2822,23 +2805,25 @@ void UV_OT_hide(wmOperatorType *ot)
 
 static int reveal_exec(bContext *C, wmOperator *op)
 {
-       SpaceImage *sima= (SpaceImage*)CTX_wm_space_data(C);
-       Scene *scene= CTX_data_scene(C);
+       SpaceImage *sima= CTX_wm_space_image(C);
+       ToolSettings *ts= CTX_data_tool_settings(C);
        Object *obedit= CTX_data_edit_object(C);
        EditMesh *em= BKE_mesh_get_editmesh((Mesh*)obedit->data);
        EditFace *efa;
        MTFace *tf;
+       int facemode= sima ? sima->flag & SI_SELACTFACE : 0;
+       int stickymode= sima ? (sima->sticky != SI_STICKY_DISABLE) : 1;
        
        /* call the mesh function if we are in mesh sync sel */
-       if(scene->toolsettings->uv_flag & UV_SYNC_SELECTION) {
+       if(ts->uv_flag & UV_SYNC_SELECTION) {
                EM_reveal_mesh(em);
-               WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit);
+               WM_event_add_notifier(C, NC_GEOM|ND_SELECT, obedit->data);
 
                BKE_mesh_end_editmesh(obedit->data, em);
                return OPERATOR_FINISHED;
        }
        
-       if(sima->flag & SI_SELACTFACE) {
+       if(facemode) {
                if(em->selectmode == SCE_SELECT_FACE) {
                        for(efa= em->faces.first; efa; efa= efa->next) {
                                if(!(efa->h) && !(efa->f & SELECT)) {
@@ -2850,7 +2835,7 @@ static int reveal_exec(bContext *C, wmOperator *op)
                }
                else {
                        /* enable adjacent faces to have disconnected UV selections if sticky is disabled */
-                       if(sima->sticky == SI_STICKY_DISABLE) {
+                       if(!stickymode) {
                                for(efa= em->faces.first; efa; efa= efa->next) {
                                        if(!(efa->h) && !(efa->f & SELECT)) {
                                                /* All verts must be unselected for the face to be selected in the UV view */
@@ -2928,7 +2913,7 @@ static int reveal_exec(bContext *C, wmOperator *op)
                                EM_select_face(efa, 1);
        }
 
-       WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit);
+       WM_event_add_notifier(C, NC_GEOM|ND_SELECT, obedit->data);
 
        BKE_mesh_end_editmesh(obedit->data, em);
        return OPERATOR_FINISHED;
@@ -3005,7 +2990,7 @@ static int set_tile_exec(bContext *C, wmOperator *op)
                return OPERATOR_CANCELLED;
 
        RNA_int_get_array(op->ptr, "tile", tile);
-       ED_uvedit_set_tile(C, CTX_data_scene(C), CTX_data_edit_object(C), ima, tile[0] + ima->xrep*tile[1], 1);
+       ED_uvedit_set_tile(C, CTX_data_scene(C), CTX_data_edit_object(C), ima, tile[0] + ima->xrep*tile[1]);
 
        ED_area_tag_redraw(CTX_wm_area(C));
 
@@ -3014,7 +2999,7 @@ static int set_tile_exec(bContext *C, wmOperator *op)
 
 static int set_tile_invoke(bContext *C, wmOperator *op, wmEvent *event)
 {
-       SpaceImage *sima= (SpaceImage*)CTX_wm_space_data(C);
+       SpaceImage *sima= CTX_wm_space_image(C);
        Image *ima= CTX_data_edit_image(C);
        ARegion *ar= CTX_wm_region(C);
        float fx, fy;
@@ -3064,7 +3049,7 @@ void UV_OT_tile_set(wmOperatorType *ot)
 void ED_operatortypes_uvedit(void)
 {
        WM_operatortype_append(UV_OT_select_all_toggle);
-       WM_operatortype_append(UV_OT_select_invert);
+       WM_operatortype_append(UV_OT_select_inverse);
        WM_operatortype_append(UV_OT_select);
        WM_operatortype_append(UV_OT_select_loop);
        WM_operatortype_append(UV_OT_select_linked);
@@ -3077,7 +3062,6 @@ void ED_operatortypes_uvedit(void)
        WM_operatortype_append(UV_OT_snap_selection);
 
        WM_operatortype_append(UV_OT_align);
-       WM_operatortype_append(UV_OT_mirror);
        WM_operatortype_append(UV_OT_stitch);
        WM_operatortype_append(UV_OT_weld);
        WM_operatortype_append(UV_OT_pin);
@@ -3102,7 +3086,10 @@ void ED_operatortypes_uvedit(void)
 
 void ED_keymap_uvedit(wmWindowManager *wm)
 {
-       ListBase *keymap= WM_keymap_listbase(wm, "UVEdit", 0, 0);
+       wmKeyMap *keymap;
+       
+       keymap= WM_keymap_find(wm, "UVEdit", 0, 0);
+       keymap->poll= ED_operator_uvedit;
        
        /* pick selection */
        WM_keymap_add_item(keymap, "UV_OT_select", SELECTMOUSE, KM_PRESS, 0, 0);
@@ -3119,7 +3106,7 @@ void ED_keymap_uvedit(wmWindowManager *wm)
        WM_keymap_add_item(keymap, "UV_OT_select_linked", LKEY, KM_PRESS, KM_CTRL, 0);
        WM_keymap_add_item(keymap, "UV_OT_unlink_selection", LKEY, KM_PRESS, KM_ALT, 0);
        WM_keymap_add_item(keymap, "UV_OT_select_all_toggle", AKEY, KM_PRESS, 0, 0);
-       WM_keymap_add_item(keymap, "UV_OT_select_invert", IKEY, KM_PRESS, KM_CTRL, 0);
+       WM_keymap_add_item(keymap, "UV_OT_select_inverse", IKEY, KM_PRESS, KM_CTRL, 0);
        WM_keymap_add_item(keymap, "UV_OT_select_pinned", PKEY, KM_PRESS, KM_SHIFT, 0);
 
        /* uv operations */