Fix #19382: crash on uv edit stitch, tweaking limit property in tool area.
[blender-staging.git] / source / blender / editors / uvedit / uvedit_ops.c
index 9051300e117cd4bf570ea35067616d4b11610c67..9216cfb5cdc96bdcf0afff545517a3d162d4a99b 100644 (file)
@@ -77,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);
@@ -180,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;
@@ -1097,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);
@@ -1255,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 **************** */
@@ -1439,7 +1445,7 @@ static int mouse_select(bContext *C, float co[2], int extend, int loop)
        else {
                sync= 0;
                selectmode= ts->uv_selectmode;
-               sticky= sima->sticky;
+               sticky= (sima)? sima->sticky: 1;
        }
 
        /* find nearest element */
@@ -2471,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;
@@ -2657,6 +2668,7 @@ static int hide_exec(bContext *C, wmOperator *op)
        EditFace *efa;
        MTFace *tf;
        int swap= RNA_boolean_get(op->ptr, "unselected");
+       int facemode= sima ? sima->flag & SI_SELACTFACE : 0;
 
        if(ts->uv_flag & UV_SYNC_SELECTION) {
                EM_hide_mesh(em, swap);
@@ -2670,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) )                      ||
@@ -2715,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)       ) {
@@ -2799,6 +2811,8 @@ static int reveal_exec(bContext *C, wmOperator *op)
        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(ts->uv_flag & UV_SYNC_SELECTION) {
@@ -2809,7 +2823,7 @@ static int reveal_exec(bContext *C, wmOperator *op)
                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)) {
@@ -2821,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 */
@@ -3072,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);