diff options
author | Campbell Barton <ideasman42@gmail.com> | 2021-03-29 06:23:49 +0300 |
---|---|---|
committer | Campbell Barton <ideasman42@gmail.com> | 2021-03-29 06:31:05 +0300 |
commit | 6af4163a3f190ed8b33a622ac038d9df88757a20 (patch) | |
tree | 6bf488d1301ad4dad521c718ecce89f621466689 /source/blender | |
parent | 27a7b2e27ae8088dccfa87e66c820dc2e37c113a (diff) |
Knife: reduce redundant face picking queries
Reduce the maximum number of queries to find the face under the
mouse cursor from 6x to 2x on cursor motion.
Calculating the screen-space detail could perform 2x look-ups
which have already been calculated.
Diffstat (limited to 'source/blender')
-rw-r--r-- | source/blender/editors/mesh/editmesh_knife.c | 82 |
1 files changed, 43 insertions, 39 deletions
diff --git a/source/blender/editors/mesh/editmesh_knife.c b/source/blender/editors/mesh/editmesh_knife.c index f8b4bf52920..1e6a2c80f91 100644 --- a/source/blender/editors/mesh/editmesh_knife.c +++ b/source/blender/editors/mesh/editmesh_knife.c @@ -1931,64 +1931,68 @@ static BMFace *knife_find_closest_face(KnifeTool_OpData *kcd, /** * Find the 2d screen space density of vertices within a radius. * Used to scale snapping distance for picking edges/verts. + * + * Arguments `f` and `cageco` should be the result of a call to #knife_find_closest_face. */ -static int knife_sample_screen_density(KnifeTool_OpData *kcd, const float radius) +static int knife_sample_screen_density_from_closest_face(KnifeTool_OpData *kcd, + const float radius, + BMFace *f, + const float cageco[3]) { - BMFace *f; - bool is_space; - float co[3], cageco[3], sco[2]; - - BLI_assert(kcd->is_interactive == true); - - f = knife_find_closest_face(kcd, co, cageco, &is_space); - - if (f && !is_space) { - const float radius_sq = radius * radius; - ListBase *list; - Ref *ref; - float dis_sq; - int c = 0; + const float radius_sq = radius * radius; + ListBase *list; + Ref *ref; + float sco[2]; + float dis_sq; + int c = 0; - knife_project_v2(kcd, cageco, sco); + knife_project_v2(kcd, cageco, sco); - list = knife_get_face_kedges(kcd, f); - for (ref = list->first; ref; ref = ref->next) { - KnifeEdge *kfe = ref->ref; - int i; + list = knife_get_face_kedges(kcd, f); + for (ref = list->first; ref; ref = ref->next) { + KnifeEdge *kfe = ref->ref; + int i; - for (i = 0; i < 2; i++) { - KnifeVert *kfv = i ? kfe->v2 : kfe->v1; - float kfv_sco[2]; + for (i = 0; i < 2; i++) { + KnifeVert *kfv = i ? kfe->v2 : kfe->v1; + float kfv_sco[2]; - knife_project_v2(kcd, kfv->cageco, kfv_sco); + knife_project_v2(kcd, kfv->cageco, kfv_sco); - dis_sq = len_squared_v2v2(kfv_sco, sco); - if (dis_sq < radius_sq) { - if (RV3D_CLIPPING_ENABLED(kcd->vc.v3d, kcd->vc.rv3d)) { - if (ED_view3d_clipping_test(kcd->vc.rv3d, kfv->cageco, true) == 0) { - c++; - } - } - else { + dis_sq = len_squared_v2v2(kfv_sco, sco); + if (dis_sq < radius_sq) { + if (RV3D_CLIPPING_ENABLED(kcd->vc.v3d, kcd->vc.rv3d)) { + if (ED_view3d_clipping_test(kcd->vc.rv3d, kfv->cageco, true) == 0) { c++; } } + else { + c++; + } } } - - return c; } - return 0; + return c; } -/* returns snapping distance for edges/verts, scaled by the density of the - * surrounding mesh (in screen space)*/ +/** + * \return the snapping distance for edges/verts, scaled by the density of the + * surrounding mesh (in screen space). + * + * \note Face values in `kcd->curr` must be up to date. + */ static float knife_snap_size(KnifeTool_OpData *kcd, float maxsize) { - float density = (float)knife_sample_screen_density(kcd, maxsize * 2.0f); + BLI_assert(kcd->is_interactive == true); + int density = 0; + + if (!kcd->curr.is_space) { + density = (float)knife_sample_screen_density_from_closest_face( + kcd, maxsize * 2.0f, kcd->curr.bmface, kcd->curr.cage); + } - return min_ff(maxsize / (density * 0.5f), maxsize); + return density ? min_ff(maxsize / ((float)density * 0.5f), maxsize) : maxsize; } /* p is closest point on edge to the mouse cursor */ |