[Bf-blender-cvs] [7d476a3af01] soc-2021-curves: Fixed segment jump issue

dilithjay noreply at git.blender.org
Sat Dec 4 17:40:41 CET 2021


Commit: 7d476a3af010570d01801bc8091e53aeed2c3e51
Author: dilithjay
Date:   Sat Dec 4 15:13:06 2021 +0530
Branches: soc-2021-curves
https://developer.blender.org/rB7d476a3af010570d01801bc8091e53aeed2c3e51

Fixed segment jump issue

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

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 f75da620454..f3b9ae5bcf0 100644
--- a/source/blender/editors/curve/editcurve_pen.c
+++ b/source/blender/editors/curve/editcurve_pen.c
@@ -69,6 +69,8 @@ typedef struct MoveSegmentData {
   Nurb *nu;
   /* Index of the #BezTriple before the segment. */
   int bezt_index;
+  /* Fraction along the segment at which mouse was pressed. */
+  float t;
 } MoveSegmentData;
 
 static void mouse_location_to_worldspace(const int mouse_loc[2],
@@ -232,7 +234,7 @@ static bool get_closest_point_on_edge(float r_point[3],
                                       const float pos1[3],
                                       const float pos2[3],
                                       const ViewContext *vc,
-                                      float *r_factor)
+                                      float *r_fraction)
 {
   float pos1_2d[2], pos2_2d[2], vec1[2], vec2[2], vec3[2];
 
@@ -259,19 +261,21 @@ static bool get_closest_point_on_edge(float r_point[3],
   perpendicular line from the mouse to the line.*/
   if ((dot1 > 0) == (dot2 > 0)) {
     float len_vec3_sq = len_squared_v2(vec3);
-    *r_factor = 1 - dot2 / len_vec3_sq;
+    *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_factor);
+    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;
 }
 
@@ -501,20 +505,28 @@ static void update_data_for_all_nurbs(const ListBase *nurbs, const ViewContext *
         update_data_if_closest_point_in_segment(bezt + 1, nu->bezt, nu, nu->pntsu - 1, vc, data);
       }
 
-      float point[3], factor;
+      float point[3], fraction;
       bool found_min = get_closest_point_on_edge(
-          point, data->mval, data->cut_loc, data->next_loc, vc, &factor);
+          point, data->mval, data->cut_loc, data->next_loc, vc, &fraction);
       bool check = ED_view3d_project_float_object(
           vc->region, point, screen_co, V3D_PROJ_RET_CLIP_BB | V3D_PROJ_RET_CLIP_WIN);
       const float dist1 = len_manhattan_v3v3(screen_co, data->mval);
 
+      data->min_dist = dist1;
+
       found_min = get_closest_point_on_edge(
-          point, data->mval, data->cut_loc, data->prev_loc, vc, &factor);
+          point, data->mval, data->cut_loc, data->prev_loc, vc, &fraction);
       check = ED_view3d_project_float_object(
           vc->region, point, screen_co, V3D_PROJ_RET_CLIP_BB | V3D_PROJ_RET_CLIP_WIN);
       const float dist2 = len_manhattan_v3v3(screen_co, data->mval);
 
-      data->min_dist = min_fff(dist1, dist2, data->min_dist);
+      if (dist2 < dist1) {
+        data->parameter -= fraction / nu->resolu;
+        data->min_dist = dist2;
+      }
+      else {
+        data->parameter += fraction / nu->resolu;
+      }
     }
     else {
       float screen_co[2];
@@ -741,6 +753,7 @@ static bool is_spline_nearby(ViewContext *vc, wmOperator *op, const wmEvent *eve
     op->customdata = seg_data = MEM_callocN(sizeof(MoveSegmentData), __func__);
     seg_data->bezt_index = data.bezt_index;
     seg_data->nu = data.nurb;
+    seg_data->t = data.parameter;
     return true;
   }
   return false;
@@ -753,6 +766,13 @@ static void move_segment(MoveSegmentData *seg_data, const wmEvent *event, ViewCo
   BezTriple *bezt1 = nu->bezt + seg_data->bezt_index;
   BezTriple *bezt2 = BKE_nurb_bezt_get_next(nu, bezt1);
 
+  const float t = seg_data->t;
+  const float t_sq = t * t;
+  const float t_cu = t_sq * t;
+  const float one_minus_t = 1 - t;
+  const float one_minus_t_sq = one_minus_t * one_minus_t;
+  const float one_minus_t_cu = one_minus_t_sq * one_minus_t;
+
   float mouse_3d[3];
   float depth[3];
   /* Use the center of the spline segment as depth. */
@@ -771,17 +791,18 @@ static void move_segment(MoveSegmentData *seg_data, const wmEvent *event, ViewCo
    * The minima can be found by differentiating the total distance.
    */
 
-  float p1_plus_p2_div_2[3];
-  p1_plus_p2_div_2[0] = (8.0f * mouse_3d[0] - bezt1->vec[1][0] - bezt2->vec[1][0]) / 6.0f;
-  p1_plus_p2_div_2[1] = (8.0f * mouse_3d[1] - bezt1->vec[1][1] - bezt2->vec[1][1]) / 6.0f;
-  p1_plus_p2_div_2[2] = (8.0f * mouse_3d[2] - bezt1->vec[1][2] - bezt2->vec[1][2]) / 6.0f;
+  float k1[3];
+  sub_v3_v3v3(k1, bezt1->vec[2], bezt2->vec[0]);
 
-  float p1_minus_p2_div_2[3];
-  sub_v3_v3v3(p1_minus_p2_div_2, bezt1->vec[2], bezt2->vec[0]);
-  mul_v3_fl(p1_minus_p2_div_2, 0.5f);
+  float k2[3];
+  const float denom = (3.0f * one_minus_t * t_sq);
+  k2[0] = (mouse_3d[0] - one_minus_t_cu * bezt1->vec[1][0] - t_cu * bezt2->vec[1][0]) / denom;
+  k2[1] = (mouse_3d[1] - one_minus_t_cu * bezt1->vec[1][1] - t_cu * bezt2->vec[1][1]) / denom;
+  k2[2] = (mouse_3d[2] - one_minus_t_cu * bezt1->vec[1][2] - t_cu * bezt2->vec[1][2]) / denom;
 
-  add_v3_v3v3(bezt1->vec[2], p1_plus_p2_div_2, p1_minus_p2_div_2);
-  sub_v3_v3v3(bezt2->vec[0], p1_plus_p2_div_2, p1_minus_p2_div_2);
+  add_v3_v3v3(bezt1->vec[2], k1, k2);
+  mul_v3_fl(bezt1->vec[2], t);
+  sub_v3_v3v3(bezt2->vec[0], bezt1->vec[2], k1);
 
   free_up_handles_for_movement(bezt1, true, true);
   free_up_handles_for_movement(bezt2, true, true);



More information about the Bf-blender-cvs mailing list