merge from master
[blender.git] / source / blender / editors / uvedit / uvedit_ops.c
index f66c9ee99517d8740a370ac2093f719c05ffe649..61e0004915d2ea4c3db2377a793fcde06b30b7f8 100644 (file)
@@ -286,6 +286,21 @@ static void uvedit_pixel_to_float(SpaceImage *sima, float *dist, float pixeldist
 
 /*************** visibility and selection utilities **************/
 
+static void uvedit_vertex_select_tagged(BMEditMesh *em, Scene *scene, bool select, int cd_loop_uv_offset)
+{
+       BMFace *efa;
+       BMLoop *l;
+       BMIter iter, liter;
+
+       BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
+               BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
+                       if (BM_elem_flag_test(l->v, BM_ELEM_TAG)) {
+                               uvedit_uv_select_set(em, scene, l, select, false, cd_loop_uv_offset);
+                       }
+               }
+       }
+}
+
 bool uvedit_face_visible_nolocal(Scene *scene, BMFace *efa)
 {
        ToolSettings *ts = scene->toolsettings;
@@ -1291,9 +1306,7 @@ static int uv_select_more_less(bContext *C, const bool select)
        if (ts->uv_selectmode == UV_SELECT_FACE) {
 
                /* clear tags */
-               BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
-                       BM_elem_flag_disable(efa, BM_ELEM_TAG);
-               }
+               BM_mesh_elem_hflag_disable_all(em->bm, BM_FACE, BM_ELEM_TAG, false);
 
                /* mark loops to be selected */
                BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
@@ -1485,9 +1498,7 @@ static void uv_weld_align(bContext *C, int tool)
                BMIter iter, liter, eiter;
 
                /* clear tag */
-               BM_ITER_MESH (eve, &iter, em->bm, BM_VERTS_OF_MESH) {
-                       BM_elem_flag_disable(eve, BM_ELEM_TAG);
-               }
+               BM_mesh_elem_hflag_disable_all(em->bm, BM_VERT, BM_ELEM_TAG, false);
 
                /* tag verts with a selected UV */
                BM_ITER_MESH (eve, &iter, em->bm, BM_VERTS_OF_MESH) {
@@ -2587,12 +2598,8 @@ static void uv_select_flush_from_tag_face(SpaceImage *sima, Scene *scene, Object
        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 MLoopUV's that use a touched vert. */
-               BMVert *eve;
-               
-               BM_ITER_MESH (eve, &iter, em->bm, BM_VERTS_OF_MESH) {
-                       BM_elem_flag_disable(eve, BM_ELEM_TAG);
-               }
-               
+               BM_mesh_elem_hflag_disable_all(em->bm, BM_VERT, BM_ELEM_TAG, false);
+
                BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
                        if (BM_elem_flag_test(efa, BM_ELEM_TAG)) {
                                BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
@@ -2677,11 +2684,7 @@ static void uv_select_flush_from_tag_loop(SpaceImage *sima, Scene *scene, Object
        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 MLoopUV's that use a touched vert. */
-               BMVert *eve;
-
-               BM_ITER_MESH (eve, &iter, em->bm, BM_VERTS_OF_MESH) {
-                       BM_elem_flag_disable(eve, BM_ELEM_TAG);
-               }
+               BM_mesh_elem_hflag_disable_all(em->bm, BM_VERT, BM_ELEM_TAG, false);
 
                BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
                        BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
@@ -2802,7 +2805,8 @@ static int uv_border_select_exec(bContext *C, wmOperator *op)
        else {
                /* other selection modes */
                changed = true;
-               
+               BM_mesh_elem_hflag_disable_all(em->bm, BM_VERT, BM_ELEM_TAG, false);
+
                BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
                        if (!uvedit_face_visible_test(scene, obedit, ima, efa))
                                continue;
@@ -2814,15 +2818,21 @@ static int uv_border_select_exec(bContext *C, wmOperator *op)
                                        /* UV_SYNC_SELECTION - can't do pinned selection */
                                        if (BLI_rctf_isect_pt_v(&rectf, luv->uv)) {
                                                uvedit_uv_select_set(em, scene, l, select, false, cd_loop_uv_offset);
+                                               BM_elem_flag_enable(l->v, BM_ELEM_TAG);
                                        }
                                }
                                else if (pinned) {
                                        if ((luv->flag & MLOOPUV_PINNED) && BLI_rctf_isect_pt_v(&rectf, luv->uv)) {
                                                uvedit_uv_select_set(em, scene, l, select, false, cd_loop_uv_offset);
+                                               BM_elem_flag_enable(l->v, BM_ELEM_TAG);
                                        }
                                }
                        }
                }
+
+               if (sima->sticky == SI_STICKY_VERTEX) {
+                       uvedit_vertex_select_tagged(em, scene, select, cd_loop_uv_offset);
+               }
        }
 
        if (changed) {
@@ -2872,19 +2882,6 @@ static int uv_inside_circle(const float uv[2], const float offset[2], const floa
        return ((x * x + y * y) < 1.0f);
 }
 
-static bool uv_select_inside_ellipse(BMEditMesh *em, Scene *scene, const bool select,
-                                     const float offset[2], const float ellipse[2], BMLoop *l, MLoopUV *luv,
-                                     const int cd_loop_uv_offset)
-{
-       if (uv_inside_circle(luv->uv, offset, ellipse)) {
-               uvedit_uv_select_set(em, scene, l, select, false, cd_loop_uv_offset);
-               return true;
-       }
-       else {
-               return false;
-       }
-}
-
 static int uv_circle_select_exec(bContext *C, wmOperator *op)
 {
        SpaceImage *sima = CTX_wm_space_image(C);
@@ -2944,12 +2941,22 @@ static int uv_circle_select_exec(bContext *C, wmOperator *op)
                }
        }
        else {
+               BM_mesh_elem_hflag_disable_all(em->bm, BM_VERT, BM_ELEM_TAG, false);
+
                BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
                        BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
                                luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
-                               changed |= uv_select_inside_ellipse(em, scene, select, offset, ellipse, l, luv, cd_loop_uv_offset);
+                               if (uv_inside_circle(luv->uv, offset, ellipse)) {
+                                       changed = true;
+                                       uvedit_uv_select_set(em, scene, l, select, false, cd_loop_uv_offset);
+                                       BM_elem_flag_enable(l->v, BM_ELEM_TAG);
+                               }
                        }
                }
+
+               if (sima->sticky == SI_STICKY_VERTEX) {
+                       uvedit_vertex_select_tagged(em, scene, select, cd_loop_uv_offset);
+               }
        }
 
        if (changed) {
@@ -3040,6 +3047,8 @@ static bool do_lasso_select_mesh_uv(bContext *C, const int mcords[][2], short mo
                }
        }
        else { /* Vert Sel */
+               BM_mesh_elem_hflag_disable_all(em->bm, BM_VERT, BM_ELEM_TAG, false);
+
                BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
                        if (uvedit_face_visible_test(scene, obedit, ima, efa)) {
                                BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
@@ -3053,11 +3062,16 @@ static bool do_lasso_select_mesh_uv(bContext *C, const int mcords[][2], short mo
                                                {
                                                        uvedit_uv_select_set(em, scene, l, select, false, cd_loop_uv_offset);
                                                        changed = true;
+                                                       BM_elem_flag_enable(l->v, BM_ELEM_TAG);
                                                }
                                        }
                                }
                        }
                }
+
+               if (sima->sticky == SI_STICKY_VERTEX) {
+                       uvedit_vertex_select_tagged(em, scene, select, cd_loop_uv_offset);
+               }
        }
 
        if (changed) {
@@ -3966,17 +3980,14 @@ static int uv_mark_seam_exec(bContext *C, wmOperator *op)
        BMFace *efa;
        BMLoop *loop;
        BMIter iter, liter;
-       bool clear = RNA_boolean_get(op->ptr, "clear");
+       bool flag_set = !RNA_boolean_get(op->ptr, "clear");
 
        const int cd_loop_uv_offset = CustomData_get_offset(&bm->ldata, CD_MLOOPUV);
 
        BM_ITER_MESH (efa, &iter, bm, BM_FACES_OF_MESH) {
                BM_ITER_ELEM (loop, &liter, efa, BM_LOOPS_OF_FACE) {
                        if (uvedit_edge_select_test(scene, loop, cd_loop_uv_offset)) {
-                               if (clear)
-                                       BM_elem_flag_disable(loop->e, BM_ELEM_SEAM);
-                               else
-                                       BM_elem_flag_enable(loop->e, BM_ELEM_SEAM);
+                               BM_elem_flag_set(loop->e, BM_ELEM_SEAM, flag_set);
                        }
                }
        }