[Bf-blender-cvs] [81be53bf88c] soc-2021-curves: Improved insert point algorithm

Dilith Jayakody noreply at git.blender.org
Sat Feb 5 13:28:31 CET 2022


Commit: 81be53bf88ce46870cbd4382afb6ae498f52c307
Author: Dilith Jayakody
Date:   Sat Feb 5 17:49:39 2022 +0530
Branches: soc-2021-curves
https://developer.blender.org/rB81be53bf88ce46870cbd4382afb6ae498f52c307

Improved insert point algorithm

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

M	source/blender/editors/curve/editcurve_pen.c

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

diff --git a/source/blender/editors/curve/editcurve_pen.c b/source/blender/editors/curve/editcurve_pen.c
index f8ffef23ff9..f3f8de715bd 100644
--- a/source/blender/editors/curve/editcurve_pen.c
+++ b/source/blender/editors/curve/editcurve_pen.c
@@ -501,54 +501,6 @@ static void delete_bp_from_nurb(const BPoint *bp, Nurb *nu)
   memmove(nu->bp + index, nu->bp + index + 1, (nu->pntsu - index) * sizeof(BPoint));
 }
 
-/* Get the closest point on an edge to a given point based on perpendicular distance. Return true
- * if the closest point falls on the edge.  */
-static bool get_closest_point_on_edge(float r_point[3],
-                                      const float pos[2],
-                                      const float pos1[3],
-                                      const float pos2[3],
-                                      const ViewContext *vc,
-                                      float *r_fraction)
-{
-  float pos1_2d[2], pos2_2d[2], vec1[2], vec2[2], vec3[2];
-
-  /* Get screen space coordinates of points. */
-  if (!(worldspace_to_screenspace(pos1, vc, pos1_2d) &&
-        worldspace_to_screenspace(pos2, vc, pos2_2d))) {
-    return false;
-  }
-
-  /* Obtain the vectors of each side. */
-  sub_v2_v2v2(vec1, pos, pos1_2d);
-  sub_v2_v2v2(vec2, pos2_2d, pos);
-  sub_v2_v2v2(vec3, pos2_2d, pos1_2d);
-
-  const float dot1 = dot_v2v2(vec1, vec3);
-  const float dot2 = dot_v2v2(vec2, vec3);
-
-  /* Compare the dot products to identify if both angles are optuse/acute or
-  opposite to each other. If they're the same, that indicates that there is a
-  perpendicular line from the mouse to the line.*/
-  if ((dot1 > 0) == (dot2 > 0)) {
-    const float len_vec3_sq = len_squared_v2(vec3);
-    *r_fraction = 1 - dot2 / len_vec3_sq;
-
-    float pos_dif[3];
-    sub_v3_v3v3(pos_dif, pos2, pos1);
-    madd_v3_v3v3fl(r_point, pos1, pos_dif, *r_fraction);
-    return true;
-  }
-
-  if (len_manhattan_v2(vec1) < len_manhattan_v2(vec2)) {
-    copy_v3_v3(r_point, pos1);
-    *r_fraction = 0.0f;
-    return false;
-  }
-  copy_v3_v3(r_point, pos2);
-  *r_fraction = 1.0f;
-  return false;
-}
-
 /* Get closest vertex in all nurbs in given #ListBase to a given point.
  * Returns true if point is found. */
 static bool get_closest_vertex_to_point_in_nurbs(const ListBase *nurbs,
@@ -629,70 +581,6 @@ static bool get_closest_vertex_to_point_in_nurbs(const ListBase *nurbs,
   return false;
 }
 
-/* Assign values for several frequently changing attributes of #CutData. */
-static void assign_cut_data(CutData *data,
-                            Nurb *nu,
-                            const float min_dist,
-                            const int bezt_index,
-                            const int bp_index,
-                            const float parameter,
-                            const float cut_loc[3])
-{
-  data->min_dist = min_dist;
-  data->nurb = nu;
-  data->bezt_index = bezt_index;
-  data->bp_index = bp_index;
-  data->parameter = parameter;
-  copy_v3_v3(data->cut_loc, cut_loc);
-}
-
-/* Iterate over all the geometry between the segment formed by bezt1 and bezt2
- * to find the closest edge to #data->mval (mouse location) and update #data->prev_loc
- * and #data->next_loc with the vertices of the edge. */
-static void update_data_if_closest_point_in_segment(const BezTriple *bezt1,
-                                                    const BezTriple *bezt2,
-                                                    Nurb *nu,
-                                                    const int index,
-                                                    const ViewContext *vc,
-                                                    CutData *data)
-{
-  const float resolu = nu->resolu;
-  float *points = MEM_mallocN(sizeof(float[3]) * (resolu + 1), __func__);
-
-  /* Calculate all points on curve. */
-  for (int j = 0; j < 3; j++) {
-    BKE_curve_forward_diff_bezier(bezt1->vec[1][j],
-                                  bezt1->vec[2][j],
-                                  bezt2->vec[0][j],
-                                  bezt2->vec[1][j],
-                                  points + j,
-                                  resolu,
-                                  sizeof(float[3]));
-  }
-
-  for (int k = 0; k <= resolu; k++) {
-    float screen_co[2];
-    const bool check = worldspace_to_screenspace(points + 3 * k, vc, screen_co);
-
-    if (check) {
-      const float distance = len_manhattan_v2v2(screen_co, data->mval);
-      if (distance < data->min_dist) {
-        assign_cut_data(data, nu, distance, index, -1, ((float)k) / resolu, points + 3 * k);
-
-        data->has_prev = k > 0;
-        data->has_next = k < resolu;
-        if (data->has_prev) {
-          copy_v3_v3(data->prev_loc, points + 3 * (k - 1));
-        }
-        if (data->has_next) {
-          copy_v3_v3(data->next_loc, points + 3 * (k + 1));
-        }
-      }
-    }
-  }
-  MEM_freeN(points);
-}
-
 /* Interpolate along the Bezier segment by a parameter (between 0 and 1) and get its location. */
 static void get_bezier_interpolated_point(float r_point[3],
                                           const BezTriple *bezt1,
@@ -708,38 +596,6 @@ static void get_bezier_interpolated_point(float r_point[3],
   interp_v3_v3v3(r_point, tmp1, tmp2, parameter);
 }
 
-/* Update the closest location as cut location in data. */
-static void update_cut_loc_in_data(CutData *data, const ViewContext *vc)
-{
-  bool found_min = false;
-  float point[3], factor;
-
-  if (data->has_prev) {
-    found_min = get_closest_point_on_edge(
-        point, data->mval, data->cut_loc, data->prev_loc, vc, &factor);
-    factor = -factor;
-  }
-  if (!found_min && data->has_next) {
-    found_min = get_closest_point_on_edge(
-        point, data->mval, data->cut_loc, data->next_loc, vc, &factor);
-  }
-  if (found_min) {
-    float point_2d[2];
-    if (worldspace_to_screenspace(point, vc, point_2d)) {
-      return;
-    }
-    const float dist = len_manhattan_v2v2(point_2d, data->mval);
-    data->min_dist = dist;
-    data->parameter += factor / data->nurb->resolu;
-
-    Nurb *nu = data->nurb;
-    get_bezier_interpolated_point(data->cut_loc,
-                                  &nu->bezt[data->bezt_index],
-                                  &nu->bezt[(data->bezt_index + 1) % (nu->pntsu)],
-                                  data->parameter);
-  }
-}
-
 /* Calculate handle positions of added and adjacent control points such that shape is preserved. */
 static void calculate_new_bezier_point(const float point_prev[3],
                                        float handle_prev[3],
@@ -757,75 +613,6 @@ static void calculate_new_bezier_point(const float point_prev[3],
   interp_v3_v3v3(new_right_handle, center_point, handle_next, parameter);
 }
 
-/* Update the nearest point data for all nurbs. */
-static void update_data_for_all_nurbs(const ListBase *nurbs, const ViewContext *vc, CutData *data)
-{
-  LISTBASE_FOREACH (Nurb *, nu, nurbs) {
-    if (nu->type == CU_BEZIER) {
-      float screen_co[2];
-      if (data->nurb == NULL) {
-        worldspace_to_screenspace(nu->bezt->vec[1], vc, screen_co);
-        assign_cut_data(data, nu, FLT_MAX, 0, -1, 0.0f, nu->bezt->vec[1]);
-      }
-
-      BezTriple *bezt = NULL;
-      for (int i = 0; i < nu->pntsu - 1; i++) {
-        bezt = &nu->bezt[i];
-        update_data_if_closest_point_in_segment(bezt, bezt + 1, nu, i, vc, data);
-      }
-
-      if (nu->flagu & CU_NURB_CYCLIC && bezt) {
-        update_data_if_closest_point_in_segment(bezt + 1, nu->bezt, nu, nu->pntsu - 1, vc, data);
-      }
-
-      float point[3], fraction = 0.0f;
-      if (data->has_next) {
-        get_closest_point_on_edge(point, data->mval, data->cut_loc, data->next_loc, vc, &fraction);
-        worldspace_to_screenspace(point, vc, screen_co);
-        const float len = len_manhattan_v2v2(screen_co, data->mval);
-        data->min_dist = len;
-      }
-
-      if (data->has_prev) {
-        get_closest_point_on_edge(point, data->mval, data->cut_loc, data->prev_loc, vc, &fraction);
-        worldspace_to_screenspace(point, vc, screen_co);
-        const float len = len_manhattan_v2v2(screen_co, data->mval);
-        if (len < data->min_dist) {
-          data->min_dist = len;
-          fraction = -fraction;
-        }
-      }
-
-      data->parameter += fraction / nu->resolu;
-    }
-    else {
-      float screen_co[2];
-      if (data->nurb == NULL) {
-        worldspace_to_screenspace(nu->bp->vec, vc, screen_co);
-        assign_cut_data(
-            data, nu, len_manhattan_v2v2(screen_co, data->mval), -1, 0, 0.0f, nu->bp->vec);
-      }
-
-      const int end = (nu->flagu & CU_NURB_CYCLIC) ? nu->pntsu : nu->pntsu - 1;
-      for (int i = 0; i < end; i++) {
-        float point[3], factor;
-        const int next_i = (i + 1) % nu->pntsu;
-        const bool found_min = get_closest_point_on_edge(
-            point, data->mval, (nu->bp + i)->vec, (nu->bp + next_i)->vec, vc, &factor);
-        if (found_min) {
-          float point_2d[2];
-          if (worldspace_to_screenspace(point, vc, point_2d)) {
-            const float dist = len_manhattan_v2v2(point_2d, data->mval);
-            if (dist < data->min_dist) {
-              assign_cut_data(data, nu, dist, -1, i, 0.0f, point);
-            }
-          }
-        }
-      }
-    }
-  }
-}
-
 /* Insert a #BezTriple to a nurb at the location specified by `op_data`. */
 static void insert_bezt_to_nurb(Nurb *nu, const CutData *data, Curve *cu)
 {
@@ -924,10 +711,141 @@ static void insert_bp_to_nurb(Nurb *nu, const CutData *data, Curve *cu)
   new_bp->f1 |= SELECT;
 }
 
-/* Make a cut on the nearest nurb at the closest point. Return true if spline is nearby. */
-static bool insert_point_to_segment(
-    const wmEvent *event, Curve *cu, Nurb **r_nu, const float sel_dist_mul, const ViewContext *vc)
+static void get_updated_data_for_edge(const float point[2],
+                                      const float point1[2],
+                                      const float point2[2],
+                                      const int point_idx,
+                                      const int resolu_idx,
+                                      float *min_dist,
+   

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list