[Bf-blender-cvs] [6af4163a3f1] master: Knife: reduce redundant face picking queries

Campbell Barton noreply at git.blender.org
Mon Mar 29 05:31:31 CEST 2021


Commit: 6af4163a3f190ed8b33a622ac038d9df88757a20
Author: Campbell Barton
Date:   Mon Mar 29 14:23:49 2021 +1100
Branches: master
https://developer.blender.org/rB6af4163a3f190ed8b33a622ac038d9df88757a20

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.

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

M	source/blender/editors/mesh/editmesh_knife.c

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

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 */



More information about the Bf-blender-cvs mailing list