Commit: 8010672bbc1a89e2b7c30bc22e936052325e4b75
Author: Campbell Barton
Date:   Thu Apr 23 16:11:54 2015 +1000
Branches: master
https://developer.blender.org/rB8010672bbc1a89e2b7c30bc22e936052325e4b75

BMesh: mesh-data picking, edge+vert improvement

When zoomed out vert bias over edges meant it wasn't possible to select edges.
Now pick the edge if the cursor is closer to its center.

===================================================================

M       source/blender/editors/include/ED_mesh.h
M       source/blender/editors/mesh/editmesh_select.c

===================================================================

diff --git a/source/blender/editors/include/ED_mesh.h 
b/source/blender/editors/include/ED_mesh.h
index b982ff2..55a254c 100644
--- a/source/blender/editors/include/ED_mesh.h
+++ b/source/blender/editors/include/ED_mesh.h
@@ -137,17 +137,23 @@ bool EDBM_backbuf_border_mask_init(struct ViewContext 
*vc, const int mcords[][2]
                                    short xmin, short ymin, short xmax, short 
ymax);
 bool EDBM_backbuf_circle_init(struct ViewContext *vc, short xs, short ys, 
short rads);
 
-struct BMVert *EDBM_vert_find_nearest_ex(struct ViewContext *vc, float *r_dist,
+struct BMVert *EDBM_vert_find_nearest_ex(
+        struct ViewContext *vc, float *r_dist,
         const bool use_select_bias, bool use_cycle);
 struct BMVert *EDBM_vert_find_nearest(
         struct ViewContext *vc, float *r_dist);
 
-struct BMEdge *EDBM_edge_find_nearest_ex(struct ViewContext *vc, float *r_dist,
-        const bool use_select_bias, const bool use_cycle);
+struct BMEdge *EDBM_edge_find_nearest_ex(
+        struct ViewContext *vc,float *r_dist,
+        float *r_dist_center,
+        const bool use_select_bias, const bool use_cycle,
+        struct BMEdge **r_eed_zbuf);
 struct BMEdge *EDBM_edge_find_nearest(
         struct ViewContext *vc, float *r_dist);
 
-struct BMFace *EDBM_face_find_nearest_ex(struct ViewContext *vc, float *r_dist,
+struct BMFace *EDBM_face_find_nearest_ex(
+        struct ViewContext *vc, float *r_dist,
+        float *r_dist_center,
         const bool use_select_bias, const bool use_cycle,
         struct BMFace **r_efa_zbuf);
 struct BMFace *EDBM_face_find_nearest(
diff --git a/source/blender/editors/mesh/editmesh_select.c 
b/source/blender/editors/mesh/editmesh_select.c
index 90b683c..3760ebc 100644
--- a/source/blender/editors/mesh/editmesh_select.c
+++ b/source/blender/editors/mesh/editmesh_select.c
@@ -489,11 +489,42 @@ BMVert *EDBM_vert_find_nearest(ViewContext *vc, float 
*r_dist)
        return EDBM_vert_find_nearest_ex(vc, r_dist, false, false);
 }
 
+/* find the distance to the edge we already have */
+struct NearestEdgeUserData_ZBuf {
+       float mval_fl[2];
+       float dist;
+       const BMEdge *edge_test;
+};
+
+static void find_nearest_edge_center__doZBuf(
+        void *userData, BMEdge *eed,
+        const float screen_co_a[2], const float screen_co_b[2],
+        int UNUSED(index))
+{
+       struct NearestEdgeUserData_ZBuf *data = userData;
+
+       if (eed == data->edge_test) {
+               float dist_test;
+               float screen_co_mid[2];
+
+               mid_v2_v2v2(screen_co_mid, screen_co_a, screen_co_b);
+               dist_test = len_manhattan_v2v2(data->mval_fl, screen_co_mid);
+
+               if (dist_test < data->dist) {
+                       data->dist = dist_test;
+               }
+       }
+}
+
 struct NearestEdgeUserData_Hit {
        float   dist;
        float   dist_bias;
        int     index;
        BMEdge *edge;
+
+       /* edges only, un-biased manhatten distance to which ever edge we pick
+        * (not used for choosing) */
+       float   dist_center;
 };
 
 struct NearestEdgeUserData {
@@ -508,7 +539,10 @@ struct NearestEdgeUserData {
 };
 
 /* note; uses v3d, so needs active 3d window */
-static void findnearestedge__doClosest(void *userData, BMEdge *eed, const 
float screen_co_a[2], const float screen_co_b[2], int index)
+static void find_nearest_edge__doClosest(
+        void *userData, BMEdge *eed,
+        const float screen_co_a[2], const float screen_co_b[2],
+        int index)
 {
        struct NearestEdgeUserData *data = userData;
        float dist_test, dist_test_bias;
@@ -544,10 +578,15 @@ static void findnearestedge__doClosest(void *userData, 
BMEdge *eed, const float
        }
 
        if (dist_test_bias < data->hit.dist_bias) {
+               float screen_co_mid[2];
+
                data->hit.dist_bias = dist_test_bias;
                data->hit.dist = dist_test;
                data->hit.index = index;
                data->hit.edge = eed;
+
+               mid_v2_v2v2(screen_co_mid, screen_co_a, screen_co_b);
+               data->hit.dist_center = len_manhattan_v2v2(data->mval_fl, 
screen_co_mid);
        }
 
        if (data->use_cycle) {
@@ -555,23 +594,30 @@ static void findnearestedge__doClosest(void *userData, 
BMEdge *eed, const float
                    (index > data->cycle_index_prev) &&
                    (dist_test_bias < FIND_NEAR_CYCLE_THRESHOLD_MIN))
                {
+                       float screen_co_mid[2];
+
                        data->hit_cycle.dist_bias = dist_test_bias;
                        data->hit_cycle.dist = dist_test;
                        data->hit_cycle.index = index;
                        data->hit_cycle.edge = eed;
+
+                       mid_v2_v2v2(screen_co_mid, screen_co_a, screen_co_b);
+                       data->hit_cycle.dist_center = 
len_manhattan_v2v2(data->mval_fl, screen_co_mid);
                }
        }
 }
 
 BMEdge *EDBM_edge_find_nearest_ex(
         ViewContext *vc, float *r_dist,
-        const bool use_select_bias, const bool use_cycle)
+        float *r_dist_center,
+        const bool use_select_bias, const bool use_cycle,
+        BMEdge **r_eed_zbuf)
 {
        BMesh *bm = vc->em->bm;
 
        if (V3D_IS_ZBUF(vc->v3d)) {
                const int dist_px = ED_view3d_backbuf_sample_size_clamp(vc->ar, 
*r_dist);
-               float dist_test;
+               float dist_test = 0.0f;
                unsigned int index;
                BMEdge *eed;
                
@@ -579,7 +625,28 @@ BMEdge *EDBM_edge_find_nearest_ex(
 
                index = ED_view3d_backbuf_sample_rect(vc, vc->mval, dist_px, 
bm_solidoffs, bm_wireoffs, &dist_test);
                eed = index ? BM_edge_at_index_find_or_table(bm, index - 1) : 
NULL;
-               
+
+               if (r_eed_zbuf) {
+                       *r_eed_zbuf = eed;
+               }
+
+               /* exception for faces (verts don't need this) */
+               if (r_dist_center && eed) {
+                       struct NearestEdgeUserData_ZBuf data;
+
+                       data.mval_fl[0] = vc->mval[0];
+                       data.mval_fl[1] = vc->mval[1];
+                       data.dist = FLT_MAX;
+                       data.edge_test = eed;
+
+                       ED_view3d_init_mats_rv3d(vc->obedit, vc->rv3d);
+
+                       mesh_foreachScreenEdge(vc, 
find_nearest_edge_center__doZBuf, &data, V3D_PROJ_TEST_CLIP_DEFAULT);
+
+                       *r_dist_center = data.dist;
+               }
+               /* end exception */
+
                if (eed) {
                        if (dist_test < *r_dist) {
                                *r_dist = dist_test;
@@ -614,10 +681,11 @@ BMEdge *EDBM_edge_find_nearest_ex(
                data.cycle_index_prev = prev_select_index;
 
                ED_view3d_init_mats_rv3d(vc->obedit, vc->rv3d);
-               mesh_foreachScreenEdge(vc, findnearestedge__doClosest, &data, 
clip_flag);
+               mesh_foreachScreenEdge(vc, find_nearest_edge__doClosest, &data, 
clip_flag);
 
                hit = (data.use_cycle && data.hit_cycle.edge) ? &data.hit_cycle 
: &data.hit;
                *r_dist = hit->dist;
+               *r_dist_center = hit->dist_center;
 
                prev_select_elem = hit->edge;
                prev_select_index = hit->index;
@@ -629,7 +697,7 @@ BMEdge *EDBM_edge_find_nearest_ex(
 BMEdge *EDBM_edge_find_nearest(
         ViewContext *vc, float *r_dist)
 {
-       return EDBM_edge_find_nearest_ex(vc, r_dist, false, false);
+       return EDBM_edge_find_nearest_ex(vc, r_dist, false, false, false, NULL);
 }
 
 /* find the distance to the face we already have */
@@ -639,7 +707,7 @@ struct NearestFaceUserData_ZBuf {
        const BMFace *face_test;
 };
 
-static void findnearestface__doZBuf(void *userData, BMFace *efa, const float 
screen_co[2], int UNUSED(index))
+static void find_nearest_face_center__doZBuf(void *userData, BMFace *efa, 
const float screen_co[2], int UNUSED(index))
 {
        struct NearestFaceUserData_ZBuf *data = userData;
 
@@ -704,13 +772,14 @@ static void findnearestface__doClosest(void *userData, 
BMFace *efa, const float
 
 BMFace *EDBM_face_find_nearest_ex(
         ViewContext *vc, float *r_dist,
+        float *r_dist_center,
         const bool use_select_bias, const bool use_cycle,
         BMFace **r_efa_zbuf)
 {
        BMesh *bm = vc->em->bm;
 
        if (V3D_IS_ZBUF(vc->v3d)) {
-               float dist_test;
+               float dist_test = 0.0f;
                unsigned int index;
                BMFace *efa;
 
@@ -723,8 +792,8 @@ BMFace *EDBM_face_find_nearest_ex(
                        *r_efa_zbuf = efa;
                }
 
-               /* exception for faces (verts/edges don't need this) */
-               if (efa) {
+               /* exception for faces (verts don't need this) */
+               if (r_dist_center && efa) {
                        struct NearestFaceUserData_ZBuf data;
 
                        data.mval_fl[0] = vc->mval[0];
@@ -734,9 +803,9 @@ BMFace *EDBM_face_find_nearest_ex(
 
                        ED_view3d_init_mats_rv3d(vc->obedit, vc->rv3d);
 
-                       mesh_foreachScreenFace(vc, findnearestface__doZBuf, 
&data, V3D_PROJ_TEST_CLIP_DEFAULT);
+                       mesh_foreachScreenFace(vc, 
find_nearest_face_center__doZBuf, &data, V3D_PROJ_TEST_CLIP_DEFAULT);
 
-                       dist_test = data.dist;
+                       *r_dist_center = data.dist;
                }
                /* end exception */
 
@@ -775,7 +844,7 @@ BMFace *EDBM_face_find_nearest_ex(
                mesh_foreachScreenFace(vc, findnearestface__doClosest, &data, 
clip_flag);
 
                hit = (data.use_cycle && data.hit_cycle.face) ? &data.hit_cycle 
: &data.hit;
-               *r_dist = hit->dist;
+               *r_dist = *r_dist_center = hit->dist;
 
                prev_select_elem = hit->face;
                prev_select_index = hit->index;
@@ -786,7 +855,7 @@ BMFace *EDBM_face_find_nearest_ex(
 
 BMFace *EDBM_face_find_nearest(ViewContext *vc, float *r_dist)
 {
-       return EDBM_face_find_nearest_ex(vc, r_dist, false, false, NULL);
+       return EDBM_face_find_nearest_ex(vc, r_dist, NULL, false, false, NULL);
 }
 
 #undef FIND_NEAR_SELECT_BIAS
@@ -806,9 +875,10 @@ static int unified_findnearest(ViewContext *vc, BMVert 
**r_eve, BMEdge **r_eed,
        const bool use_cycle = ((mval_prev[0] == vc->mval[0]) && (mval_prev[1] 
== vc->mval[1]));
        const float dist_init = ED_view3d_select_dist_px();
        /* since edges select lines, we give dots advantage of ~20 pix */
-       const float dist_bias = (dist_init / 4);
+       const float dist_margin = (dist_init / 2);
        float dist = dist_init;
        BMFace *efa_zbuf = NULL;
+       BMEdge *eed_zbuf = NULL;
        
        BMVert *eve = NULL;
        BMEdge *eed = NULL;
@@ -819,13 +889,20 @@ static int unified_findnearest(ViewContext *vc, BMVert 
**r_eve, BMEdge **r_eed,
        ED_view3d_backbuf_validate(vc);
 
        if ((dist > 0.0f) && em->selectmode & SCE_SELECT_FACE) {
-               efa = EDBM_face_find_nearest_ex(vc, &dist, true, use_cycle, 
&efa_zbuf);
+               float dist_center = 0.0f;
+               float *dist_center_p = (em->selectmode & (SCE_SELECT_EDGE | 
SCE_SELECT_VERTEX)) ? &dist_center : NULL;
+               efa = EDBM_face_find_nearest_ex(vc, &dist, dist_center_p, true, 
use_cycle, &efa_zbuf);
+               if (efa && dist_center_p) {
+                       dist = min_ff(dist_margin, dist_center);
+               }
        }
 
        if ((dist > 0.0f) && (em->selectmode & SCE_SELECT_EDGE)) {
-               eed = EDBM_edge_find_nearest_ex(vc, &dist, true, use_cycle);
-               if (eed) {
-                       dist = min_ff(dist + dist_bias, dist_init);
+               float dist_center = 0.0f;
+               float *dist_center_p = (em->selectmode & SCE_SELECT_VERTEX) ? 
&dist_center : NULL;
+               eed = EDB

@@ Diff output truncated at 10240 characters. @@

_______________________________________________
Bf-blender-cvs mailing list
[email protected]
http://lists.blender.org/mailman/listinfo/bf-blender-cvs

Reply via email to