[Bf-blender-cvs] [924578ce190] master: Optimization: Don't compute the snap to face on the knife tool twice

Germano Cavalcante noreply at git.blender.org
Mon Jul 6 14:49:09 CEST 2020


Commit: 924578ce190e3f6c16b45f58ec61f8dff4deb9ac
Author: Germano Cavalcante
Date:   Mon Jul 6 09:49:00 2020 -0300
Branches: master
https://developer.blender.org/rB924578ce190e3f6c16b45f58ec61f8dff4deb9ac

Optimization: Don't compute the snap to face on the knife tool twice

Both `knife_find_closest_vert` and `knife_find_closest_edge` call
`knife_find_closest_face`. Thus, running the raycast twice and setting
values like `kcd->curr.bmface` and `kcd->curr.is_space` repeatedly.

So:
- separate `knife_find_closest_face` from `knife_find_closest_vert` and `knife_find_closest_edge`.
- rename `knife_find_closest_vert` to `knife_find_closest_vert_of_face`
- rename `knife_find_closest_edge `to `knife_find_closest_edge_of_face`.
- do not set parameters previously set.

Differential Revision: https://developer.blender.org/D8198

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

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 adc3be6b2ac..d95985a5515 100644
--- a/source/blender/editors/mesh/editmesh_knife.c
+++ b/source/blender/editors/mesh/editmesh_knife.c
@@ -1961,11 +1961,12 @@ static float knife_snap_size(KnifeTool_OpData *kcd, float maxsize)
 }
 
 /* p is closest point on edge to the mouse cursor */
-static KnifeEdge *knife_find_closest_edge(
-    KnifeTool_OpData *kcd, float p[3], float cagep[3], BMFace **fptr, bool *is_space)
+static KnifeEdge *knife_find_closest_edge_of_face(KnifeTool_OpData *kcd,
+                                                  BMFace *f,
+                                                  float p[3],
+                                                  float cagep[3])
 {
-  BMFace *f;
-  float co[3], cageco[3], sco[2];
+  float sco[2];
   float maxdist;
 
   if (kcd->is_interactive) {
@@ -1979,127 +1980,107 @@ static KnifeEdge *knife_find_closest_edge(
     maxdist = KNIFE_FLT_EPS;
   }
 
-  f = knife_find_closest_face(kcd, co, cageco, NULL);
-  *is_space = !f;
-
-  kcd->curr.bmface = f;
-
-  if (f) {
-    const float maxdist_sq = maxdist * maxdist;
-    KnifeEdge *cure = NULL;
-    float cur_cagep[3];
-    ListBase *lst;
-    Ref *ref;
-    float dis_sq, curdis_sq = FLT_MAX;
-
-    /* set p to co, in case we don't find anything, means a face cut */
-    copy_v3_v3(p, co);
-    copy_v3_v3(cagep, cageco);
-
-    knife_project_v2(kcd, cageco, sco);
-
-    /* look through all edges associated with this face */
-    lst = knife_get_face_kedges(kcd, f);
-    for (ref = lst->first; ref; ref = ref->next) {
-      KnifeEdge *kfe = ref->ref;
-      float test_cagep[3];
-      float lambda;
-
-      /* project edge vertices into screen space */
-      knife_project_v2(kcd, kfe->v1->cageco, kfe->v1->sco);
-      knife_project_v2(kcd, kfe->v2->cageco, kfe->v2->sco);
-
-      /* check if we're close enough and calculate 'lambda' */
-      if (kcd->is_angle_snapping) {
-        /* if snapping, check we're in bounds */
-        float sco_snap[2];
-        isect_line_line_v2_point(
-            kfe->v1->sco, kfe->v2->sco, kcd->prev.mval, kcd->curr.mval, sco_snap);
-        lambda = line_point_factor_v2(sco_snap, kfe->v1->sco, kfe->v2->sco);
-
-        /* be strict about angle-snapping within edge */
-        if ((lambda < 0.0f - KNIFE_FLT_EPSBIG) || (lambda > 1.0f + KNIFE_FLT_EPSBIG)) {
-          continue;
-        }
+  const float maxdist_sq = maxdist * maxdist;
+  KnifeEdge *cure = NULL;
+  float cur_cagep[3];
+  ListBase *lst;
+  Ref *ref;
+  float dis_sq, curdis_sq = FLT_MAX;
+
+  knife_project_v2(kcd, cagep, sco);
+
+  /* look through all edges associated with this face */
+  lst = knife_get_face_kedges(kcd, f);
+  for (ref = lst->first; ref; ref = ref->next) {
+    KnifeEdge *kfe = ref->ref;
+    float test_cagep[3];
+    float lambda;
+
+    /* project edge vertices into screen space */
+    knife_project_v2(kcd, kfe->v1->cageco, kfe->v1->sco);
+    knife_project_v2(kcd, kfe->v2->cageco, kfe->v2->sco);
+
+    /* check if we're close enough and calculate 'lambda' */
+    if (kcd->is_angle_snapping) {
+      /* if snapping, check we're in bounds */
+      float sco_snap[2];
+      isect_line_line_v2_point(
+          kfe->v1->sco, kfe->v2->sco, kcd->prev.mval, kcd->curr.mval, sco_snap);
+      lambda = line_point_factor_v2(sco_snap, kfe->v1->sco, kfe->v2->sco);
+
+      /* be strict about angle-snapping within edge */
+      if ((lambda < 0.0f - KNIFE_FLT_EPSBIG) || (lambda > 1.0f + KNIFE_FLT_EPSBIG)) {
+        continue;
+      }
 
-        dis_sq = len_squared_v2v2(sco, sco_snap);
-        if (dis_sq < curdis_sq && dis_sq < maxdist_sq) {
-          /* we already have 'lambda' */
-        }
-        else {
-          continue;
-        }
+      dis_sq = len_squared_v2v2(sco, sco_snap);
+      if (dis_sq < curdis_sq && dis_sq < maxdist_sq) {
+        /* we already have 'lambda' */
       }
       else {
-        dis_sq = dist_squared_to_line_segment_v2(sco, kfe->v1->sco, kfe->v2->sco);
-        if (dis_sq < curdis_sq && dis_sq < maxdist_sq) {
-          lambda = line_point_factor_v2(sco, kfe->v1->sco, kfe->v2->sco);
-        }
-        else {
-          continue;
-        }
+        continue;
       }
-
-      /* now we have 'lambda' calculated (in screen-space) */
-      knife_interp_v3_v3v3(kcd, test_cagep, kfe->v1->cageco, kfe->v2->cageco, lambda);
-
-      if (RV3D_CLIPPING_ENABLED(kcd->vc.v3d, kcd->vc.rv3d)) {
-        /* check we're in the view */
-        if (ED_view3d_clipping_test(kcd->vc.rv3d, test_cagep, true)) {
-          continue;
-        }
+    }
+    else {
+      dis_sq = dist_squared_to_line_segment_v2(sco, kfe->v1->sco, kfe->v2->sco);
+      if (dis_sq < curdis_sq && dis_sq < maxdist_sq) {
+        lambda = line_point_factor_v2(sco, kfe->v1->sco, kfe->v2->sco);
+      }
+      else {
+        continue;
       }
-
-      cure = kfe;
-      curdis_sq = dis_sq;
-      copy_v3_v3(cur_cagep, test_cagep);
     }
 
-    if (fptr) {
-      *fptr = f;
+    /* now we have 'lambda' calculated (in screen-space) */
+    knife_interp_v3_v3v3(kcd, test_cagep, kfe->v1->cageco, kfe->v2->cageco, lambda);
+
+    if (RV3D_CLIPPING_ENABLED(kcd->vc.v3d, kcd->vc.rv3d)) {
+      /* check we're in the view */
+      if (ED_view3d_clipping_test(kcd->vc.rv3d, test_cagep, true)) {
+        continue;
+      }
     }
 
-    if (cure) {
-      if (!kcd->ignore_edge_snapping || !(cure->e)) {
-        KnifeVert *edgesnap = NULL;
+    cure = kfe;
+    curdis_sq = dis_sq;
+    copy_v3_v3(cur_cagep, test_cagep);
+  }
 
-        if (kcd->snap_midpoints) {
-          mid_v3_v3v3(p, cure->v1->co, cure->v2->co);
-          mid_v3_v3v3(cagep, cure->v1->cageco, cure->v2->cageco);
-        }
-        else {
-          float lambda = line_point_factor_v3(cur_cagep, cure->v1->cageco, cure->v2->cageco);
-          copy_v3_v3(cagep, cur_cagep);
-          interp_v3_v3v3(p, cure->v1->co, cure->v2->co, lambda);
-        }
+  if (cure) {
+    if (!kcd->ignore_edge_snapping || !(cure->e)) {
+      KnifeVert *edgesnap = NULL;
 
-        /* update mouse coordinates to the snapped-to edge's screen coordinates
-         * this is important for angle snap, which uses the previous mouse position */
-        edgesnap = new_knife_vert(kcd, p, cagep);
-        kcd->curr.mval[0] = edgesnap->sco[0];
-        kcd->curr.mval[1] = edgesnap->sco[1];
+      if (kcd->snap_midpoints) {
+        mid_v3_v3v3(p, cure->v1->co, cure->v2->co);
+        mid_v3_v3v3(cagep, cure->v1->cageco, cure->v2->cageco);
       }
       else {
-        return NULL;
+        float lambda = line_point_factor_v3(cur_cagep, cure->v1->cageco, cure->v2->cageco);
+        copy_v3_v3(cagep, cur_cagep);
+        interp_v3_v3v3(p, cure->v1->co, cure->v2->co, lambda);
       }
-    }
 
-    return cure;
-  }
-
-  if (fptr) {
-    *fptr = NULL;
+      /* update mouse coordinates to the snapped-to edge's screen coordinates
+       * this is important for angle snap, which uses the previous mouse position */
+      edgesnap = new_knife_vert(kcd, p, cagep);
+      kcd->curr.mval[0] = edgesnap->sco[0];
+      kcd->curr.mval[1] = edgesnap->sco[1];
+    }
+    else {
+      return NULL;
+    }
   }
 
-  return NULL;
+  return cure;
 }
 
 /* find a vertex near the mouse cursor, if it exists */
-static KnifeVert *knife_find_closest_vert(
-    KnifeTool_OpData *kcd, float p[3], float cagep[3], BMFace **fptr, bool *is_space)
+static KnifeVert *knife_find_closest_vert_of_face(KnifeTool_OpData *kcd,
+                                                  BMFace *f,
+                                                  float p[3],
+                                                  float cagep[3])
 {
-  BMFace *f;
-  float co[3], cageco[3], sco[2];
+  float sco[2];
   float maxdist;
 
   if (kcd->is_interactive) {
@@ -2112,84 +2093,61 @@ static KnifeVert *knife_find_closest_vert(
     maxdist = KNIFE_FLT_EPS;
   }
 
-  f = knife_find_closest_face(kcd, co, cageco, is_space);
-
-  kcd->curr.bmface = f;
-
-  if (f) {
-    const float maxdist_sq = maxdist * maxdist;
-    ListBase *lst;
-    Ref *ref;
-    KnifeVert *curv = NULL;
-    float dis_sq, curdis_sq = FLT_MAX;
-
-    /* set p to co, in case we don't find anything, means a face cut */
-    copy_v3_v3(p, co);
-    copy_v3_v3(cagep, cageco);
+  const float maxdist_sq = maxdist * maxdist;
+  ListBase *lst;
+  Ref *ref;
+  KnifeVert *curv = NULL;
+  float dis_sq, curdis_sq = FLT_MAX;
 
-    knife_project_v2(kcd, cageco, sco);
+  knife_project_v2(kcd, cagep, sco);
 
-    lst = knife_get_face_kedges(kcd, f);
-    for (ref = lst->first; ref; ref = ref->next) {
-      KnifeEdge *kfe = ref->ref;
-      int i;
+  lst = knife_get_face_kedges(kcd, f);
+  for (ref = lst->first; ref; ref = ref->next) {
+    KnifeEdge *kfe = ref->ref;
+    int i;
 
-      for (i = 0; i < 2; i++) {
-        KnifeVert *kfv = i ? kfe->v2 : kfe->v1;
+    for (i = 0; i < 2; i++) {
+      KnifeVert *kfv = i ? kfe->v2 : kfe->v1;
 
-        knife_project_v2(kcd, kfv->cageco, kfv->sco);
+      knife_project_v2(kcd, kfv->cageco, kfv->sco);
 
-        /* be strict about angle snapping, the vertex needs to be very close to the angle,
-         * or we ignore */
-        if (kcd->is_angle_snapping) {
-          if (dist_squared_to_line_segment_v2(kfv->sco, kcd->prev.mval, kcd->curr.mval) >
-              KNIFE_FLT_EPSBIG) {
-            continue;
-          }
+      /* be strict about angle snapping, the vertex needs to be very close to the angle,
+       * or we ignore */
+      if (kcd->is_angle_snapping) {
+        if (dist_squared_to_line_segment_v2(kfv->sco, kcd->prev.mval, kcd->curr.mval) >
+            KNIFE_FLT_EPSBIG) {
+          continue;
         }
+      }
 
-        dis_sq = len_squared_v2v2(kfv->sco, sco);
-        if (dis_sq < curdis_sq && dis_sq < maxdist_sq) {
-          if (RV3D_CLIPPING_ENABLED(kcd->vc.v3d, kcd->vc.rv3d)) {
-            if (ED_view3d_clipping_test(kcd->vc.rv3d, kfv->cageco, true) == 0) {
-              curv = kfv;
-              curdis_sq = dis_sq;
-            }
-          }
-          else {
+      dis_sq = len_squared_v2v2(kfv->sco, sco);
+      if (dis_sq < curdis_sq && dis_sq < maxdist_sq) {


@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list