[Bf-blender-cvs] [52d09dad9c0] master: Knife: snap refactor, prepare for snap gizmo

Germano Cavalcante noreply at git.blender.org
Tue Mar 30 07:20:46 CEST 2021


Commit: 52d09dad9c03d2214d1fde20bdc543f70b0174d3
Author: Germano Cavalcante
Date:   Tue Mar 30 14:28:58 2021 +1100
Branches: master
https://developer.blender.org/rB52d09dad9c03d2214d1fde20bdc543f70b0174d3

Knife: snap refactor, prepare for snap gizmo

Minor changes preparing for snap gizmo inclusion.

- Extract `knife_snap_edge_in_angle` into a utility function.
- Check the snap vertex on closest edge instead of the face.
- Add MODE_INVOKING state.
- Remove unnecessary NULL checks.
- Control 'ignore_edge_snapping' while dragging instead of checking
  dragging in `knife_snap_update_from_mval`.

Ref D8220

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

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 05b069b2d7f..44784846349 100644
--- a/source/blender/editors/mesh/editmesh_knife.c
+++ b/source/blender/editors/mesh/editmesh_knife.c
@@ -226,7 +226,7 @@ typedef struct KnifeTool_OpData {
 
   float clipsta, clipend;
 
-  enum { MODE_IDLE, MODE_DRAGGING, MODE_CONNECT, MODE_PANNING } mode;
+  enum { MODE_INVOKING, MODE_IDLE, MODE_DRAGGING, MODE_CONNECT, MODE_PANNING } mode;
   bool is_drag_hold;
 
   int prevmode;
@@ -1090,7 +1090,7 @@ static void knifetool_draw(const bContext *UNUSED(C), ARegion *UNUSED(region), v
     immEnd();
   }
 
-  if (kcd->prev.bmface) {
+  if (kcd->prev.bmface || kcd->prev.edge) {
     immUniformColor3ubv(kcd->colors.curpoint);
     GPU_point_size(9 * UI_DPI_FAC);
 
@@ -1099,7 +1099,15 @@ static void knifetool_draw(const bContext *UNUSED(C), ARegion *UNUSED(region), v
     immEnd();
   }
 
-  if (kcd->curr.edge) {
+  if (kcd->curr.vert) {
+    immUniformColor3ubv(kcd->colors.point);
+    GPU_point_size(11 * UI_DPI_FAC);
+
+    immBegin(GPU_PRIM_POINTS, 1);
+    immVertex3fv(pos, kcd->curr.cage);
+    immEnd();
+  }
+  else if (kcd->curr.edge) {
     immUniformColor3ubv(kcd->colors.edge);
     GPU_line_width(2.0);
 
@@ -1108,16 +1116,8 @@ static void knifetool_draw(const bContext *UNUSED(C), ARegion *UNUSED(region), v
     immVertex3fv(pos, kcd->curr.edge->v2->cageco);
     immEnd();
   }
-  else if (kcd->curr.vert) {
-    immUniformColor3ubv(kcd->colors.point);
-    GPU_point_size(11 * UI_DPI_FAC);
-
-    immBegin(GPU_PRIM_POINTS, 1);
-    immVertex3fv(pos, kcd->curr.cage);
-    immEnd();
-  }
 
-  if (kcd->curr.bmface) {
+  if (kcd->curr.bmface || kcd->curr.edge) {
     immUniformColor3ubv(kcd->colors.curpoint);
     GPU_point_size(9 * UI_DPI_FAC);
 
@@ -1997,6 +1997,36 @@ static float knife_snap_size(KnifeTool_OpData *kcd, float maxsize)
   return density ? min_ff(maxsize / ((float)density * 0.5f), maxsize) : maxsize;
 }
 
+/* Snap to edge in a specified angle.
+ * Returns 'lambda' calculated (in screen-space). */
+static bool knife_snap_edge_in_angle(KnifeTool_OpData *kcd,
+                                     const float sco[3],
+                                     const float kfv1_sco[2],
+                                     const float kfv2_sco[2],
+                                     float *r_dist_sq,
+                                     float *r_lambda)
+{
+  /* if snapping, check we're in bounds */
+  float sco_snap[2];
+  isect_line_line_v2_point(kfv1_sco, kfv2_sco, kcd->prev.mval, kcd->curr.mval, sco_snap);
+  float lambda = line_point_factor_v2(sco_snap, kfv1_sco, kfv2_sco);
+
+  /* be strict about angle-snapping within edge */
+  if ((lambda < 0.0f - KNIFE_FLT_EPSBIG) || (lambda > 1.0f + KNIFE_FLT_EPSBIG)) {
+    return false;
+  }
+
+  float dis_sq = len_squared_v2v2(sco, sco_snap);
+  if (dis_sq < *r_dist_sq) {
+    *r_dist_sq = dis_sq;
+    *r_lambda = lambda;
+    return true;
+  }
+  else {
+    return false;
+  }
+}
+
 /* p is closest point on edge to the mouse cursor */
 static KnifeEdge *knife_find_closest_edge_of_face(KnifeTool_OpData *kcd,
                                                   BMFace *f,
@@ -2022,7 +2052,7 @@ static KnifeEdge *knife_find_closest_edge_of_face(KnifeTool_OpData *kcd,
   float cur_cagep[3];
   ListBase *list;
   Ref *ref;
-  float dis_sq, curdis_sq = FLT_MAX;
+  float dis_sq, curdis_sq = maxdist_sq;
 
   knife_project_v2(kcd, cagep, sco);
 
@@ -2039,27 +2069,14 @@ static KnifeEdge *knife_find_closest_edge_of_face(KnifeTool_OpData *kcd,
 
     /* 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(kfv1_sco, kfv2_sco, kcd->prev.mval, kcd->curr.mval, sco_snap);
-      lambda = line_point_factor_v2(sco_snap, kfv1_sco, kfv2_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 {
+      dis_sq = curdis_sq;
+      if (!knife_snap_edge_in_angle(kcd, sco, kfv1_sco, kfv2_sco, &dis_sq, &lambda)) {
         continue;
       }
     }
     else {
       dis_sq = dist_squared_to_line_segment_v2(sco, kfv1_sco, kfv2_sco);
-      if (dis_sq < curdis_sq && dis_sq < maxdist_sq) {
+      if (dis_sq < curdis_sq) {
         lambda = line_point_factor_v2(sco, kfv1_sco, kfv2_sco);
       }
       else {
@@ -2082,36 +2099,31 @@ static KnifeEdge *knife_find_closest_edge_of_face(KnifeTool_OpData *kcd,
     copy_v3_v3(cur_cagep, test_cagep);
   }
 
-  if (cure) {
-    if (!kcd->ignore_edge_snapping || !(cure->e)) {
-      KnifeVert *edgesnap = NULL;
+  if (cure && !kcd->ignore_edge_snapping) {
+    KnifeVert *edgesnap = NULL;
 
-      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);
-      }
-
-      /* 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);
-      knife_project_v2(kcd, edgesnap->cageco, kcd->curr.mval);
+    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);
     }
+
+    /* 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);
+    knife_project_v2(kcd, edgesnap->cageco, kcd->curr.mval);
   }
 
   return cure;
 }
 
 /* find a vertex near the mouse cursor, if it exists */
-static KnifeVert *knife_find_closest_vert_of_face(KnifeTool_OpData *kcd,
-                                                  BMFace *f,
+static KnifeVert *knife_find_closest_vert_of_edge(KnifeTool_OpData *kcd,
+                                                  KnifeEdge *kfe,
                                                   float p[3],
                                                   float cagep[3])
 {
@@ -2129,60 +2141,48 @@ static KnifeVert *knife_find_closest_vert_of_face(KnifeTool_OpData *kcd,
   }
 
   const float maxdist_sq = maxdist * maxdist;
-  ListBase *list;
-  Ref *ref;
   KnifeVert *curv = NULL;
   float cur_kfv_sco[2];
   float dis_sq, curdis_sq = FLT_MAX;
 
   knife_project_v2(kcd, cagep, sco);
 
-  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 (int 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);
 
-      /* 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) ||
-            !ED_view3d_clipping_test(kcd->vc.rv3d, kfv->cageco, true)) {
-          curv = kfv;
-          curdis_sq = dis_sq;
-          copy_v2_v2(cur_kfv_sco, kfv_sco);
-        }
+    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) ||
+          !ED_view3d_clipping_test(kcd->vc.rv3d, kfv->cageco, true)) {
+        curv = kfv;
+        curdis_sq = dis_sq;
+        copy_v2_v2(cur_kfv_sco, kfv_sco);
       }
     }
   }
 
-  if (!kcd->ignore_vert_snapping || !(curv && curv->v)) {
-    if (curv) {
-      copy_v3_v3(p, curv->co);
-      copy_v3_v3(cagep, curv->cageco);
-
-      /* update mouse coordinates to the snapped-to vertex's screen coordinates
-       * this is important for angle snap, which uses the previous mouse position */
-      copy_v2_v2(kcd->curr.mval, cur_kfv_sco);
-    }
+  if (curv && !kcd->ignore_vert_snapping) {
+    copy_v3_v3(p, curv->co);
+    copy_v3_v3(cagep, curv->cageco);
 
-    return curv;
+    /* update mouse coordinates to the snapped-to vertex's screen coordinates
+     * this is important for angle snap, which uses the previous mouse position */
+    copy_v2_v2(kcd->curr.mval, cur_kfv_sco);
   }
 
-  return NULL;
+  return curv;
 }
 
 /**
@@ -2249,32 +2249,26 @@ static bool knife_snap_update_from_mval(KnifeTool_OpData *kcd, const float mval[
     kcd->is_angle_snapping = false;
   }
 
-  kcd->curr.bmface = knife_find_closest_face(
-      kcd, kcd->curr.co, kcd->curr.cage, &kcd->curr.is_space);
-
-  bool is_co_set = false;
+  {
+    kcd->curr.bmface = knife_find_closest_face(
+        kcd, kcd->curr.co, kcd->curr.cage, &kcd->curr.is_space);
 
-  if (kcd->curr.bmface) {
-    if (kcd->curr.is_space == false) {
-      is_co_set = true;
+    if (kcd->curr.bmface) {
+      kcd->curr.edge = knife_find_closest_edge_of_fa

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list