[Bf-blender-cvs] [09953ecb32d] soc-2021-curves: Fixed bug where cut doesn't work on cyclic curves

dilithjay noreply at git.blender.org
Thu Jun 24 11:11:21 CEST 2021


Commit: 09953ecb32ddd4913f61eabf30172ec541d79a59
Author: dilithjay
Date:   Thu Jun 24 11:04:47 2021 +0530
Branches: soc-2021-curves
https://developer.blender.org/rB09953ecb32ddd4913f61eabf30172ec541d79a59

Fixed bug where cut doesn't work on cyclic curves

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

M	release/datafiles/locale
M	release/scripts/addons
M	source/blender/editors/curve/editcurve_pen.c

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

diff --git a/release/datafiles/locale b/release/datafiles/locale
index 4833954c0ac..78591466c33 160000
--- a/release/datafiles/locale
+++ b/release/datafiles/locale
@@ -1 +1 @@
-Subproject commit 4833954c0ac85cc407e1d5a153aa11b1d1823ec0
+Subproject commit 78591466c335ab055e11729d8af814ce7ce6edc9
diff --git a/release/scripts/addons b/release/scripts/addons
index f86f25e6221..15bafef9349 160000
--- a/release/scripts/addons
+++ b/release/scripts/addons
@@ -1 +1 @@
-Subproject commit f86f25e62217264495d05f116ccb09d575fe9841
+Subproject commit 15bafef93491ac0caf7c39c27999847910c1d50d
diff --git a/source/blender/editors/curve/editcurve_pen.c b/source/blender/editors/curve/editcurve_pen.c
index aefb828b969..28e5707de16 100644
--- a/source/blender/editors/curve/editcurve_pen.c
+++ b/source/blender/editors/curve/editcurve_pen.c
@@ -315,6 +315,79 @@ static void calculate_new_bezier_point(const float *point_prev,
   interp_v3_v3v3(new_right_handle, center_point, handle_next, parameter);
 }
 
+static void update_data_if_nearest_point_in_segment(BezTriple *bezt1,
+                                                    BezTriple *bezt2,
+                                                    Nurb *nu,
+                                                    int index,
+                                                    ViewContext *vc,
+                                                    float screen_co[2],
+                                                    void *op_data)
+{
+  struct temp_bezt_data {
+    /* Index of the last bez triple before the cut. */
+    int bezt_index;
+    /* Nurb to which the cut belongs to. */
+    Nurb *nurb;
+    /* Minimum distance to curve from mouse location. */
+    float min_dist;
+    /* Ratio at which the new point divides the curve segment. */
+    float parameter;
+    /* Whether the cut has any vertices before/after it. */
+    bool has_prev, has_next;
+    /* Locations of adjacent vertices. */
+    float prev_loc[3], cut_loc[3], next_loc[3];
+    /* Mouse location as floats. */
+    float mval[2];
+  } temp_bezt_data;
+  struct temp_bezt_data *data = op_data;
+
+  float resolu = nu->resolu;
+  float *points = MEM_mallocN(sizeof(float[3]) * (resolu + 1), "makeCut_bezier");
+
+  /* Calculate all points on curve. TODO: Get existing . */
+  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]));
+  }
+
+  /* Calculate angle for middle points */
+  for (int k = 0; k <= resolu; k++) {
+    /* Convert point to screen coordinates */
+    bool check = ED_view3d_project_float_object(vc->region,
+                                                points + 3 * k,
+                                                screen_co,
+                                                V3D_PROJ_RET_CLIP_BB | V3D_PROJ_RET_CLIP_WIN) ==
+                 V3D_PROJ_RET_OK;
+
+    if (check) {
+      float distance = len_manhattan_v2v2(screen_co, data->mval);
+      if (distance < data->min_dist) {
+        data->min_dist = distance;
+        data->nurb = nu;
+        data->bezt_index = index;
+        data->parameter = ((float)k) / resolu;
+
+        copy_v3_v3(data->cut_loc, 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);
+}
+
 enum {
   PEN_MODAL_CANCEL = 1,
   PEN_MODAL_FREE_MOVE_HANDLE,
@@ -519,54 +592,16 @@ static int curve_pen_modal(bContext *C, wmOperator *op, const wmEvent *event)
                 data.min_dist = len_manhattan_v2v2(screen_co, data.mval);
                 copy_v3_v3(data.cut_loc, nu->bezt->vec[1]);
               }
-              for (int i = 0; i < nu->pntsu - 1; i++) {
+              int i;
+              for (i = 0; i < nu->pntsu - 1; i++) {
                 bezt = &nu->bezt[i];
-                float resolu = nu->resolu;
-                float *points = MEM_mallocN(sizeof(float[3]) * (resolu + 1), "makeCut_bezier");
-
-                /* Calculate all points on curve. TODO: Get existing . */
-                for (int j = 0; j < 3; j++) {
-                  BKE_curve_forward_diff_bezier(bezt->vec[1][j],
-                                                bezt->vec[2][j],
-                                                (bezt + 1)->vec[0][j],
-                                                (bezt + 1)->vec[1][j],
-                                                points + j,
-                                                resolu,
-                                                sizeof(float[3]));
-                }
-
-                /* Calculate angle for middle points */
-                for (int k = 0; k <= resolu; k++) {
-                  /* Convert point to screen coordinates */
-                  bool check = ED_view3d_project_float_object(vc.region,
-                                                              points + 3 * k,
-                                                              screen_co,
-                                                              V3D_PROJ_RET_CLIP_BB |
-                                                                  V3D_PROJ_RET_CLIP_WIN) ==
-                               V3D_PROJ_RET_OK;
-
-                  if (check) {
-                    float distance = len_manhattan_v2v2(screen_co, data.mval);
-                    if (distance < data.min_dist) {
-                      data.min_dist = distance;
-                      data.nurb = nu;
-                      data.bezt_index = i;
-                      data.parameter = ((float)k) / resolu;
-
-                      copy_v3_v3(data.cut_loc, 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);
+                update_data_if_nearest_point_in_segment(
+                    bezt, bezt + 1, nu, i, &vc, screen_co, &data);
+              }
+
+              if (nu->flagu & CU_NURB_CYCLIC) {
+                update_data_if_nearest_point_in_segment(
+                    bezt + 1, nu->bezt, nu, i, &vc, screen_co, &data);
               }
             }
           }
@@ -574,7 +609,6 @@ static int curve_pen_modal(bContext *C, wmOperator *op, const wmEvent *event)
           /* If the minimum distance found < threshold distance, make cut. */
           if (data.min_dist < threshold_distance) {
             nu = data.nurb;
-            int index = data.bezt_index + 1;
             if (nu && nu->bezt) {
               bool found_min = false;
               float point[3];
@@ -582,10 +616,11 @@ static int curve_pen_modal(bContext *C, wmOperator *op, const wmEvent *event)
               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.next_loc, data.cut_loc, &vc, &factor);
+                    point, data.mval, data.cut_loc, data.next_loc, &vc, &factor);
               }
               if (found_min) {
                 float point_2d[2];
@@ -599,26 +634,38 @@ static int curve_pen_modal(bContext *C, wmOperator *op, const wmEvent *event)
 
               BezTriple *bezt1 = (BezTriple *)MEM_mallocN((nu->pntsu + 1) * sizeof(BezTriple),
                                                           "delNurb");
+              int index = data.bezt_index + 1;
               /* Copy all control points before the cut to the new memory. */
               memcpy(bezt1, nu->bezt, index * sizeof(BezTriple));
               BezTriple *new_bezt = bezt1 + index;
 
               /* Duplicate control point after the cut. */
               memcpy(new_bezt, new_bezt - 1, sizeof(BezTriple));
-              // new_bezt->h1 = new_bezt->h2 = HD_AUTO;
               copy_v3_v3(new_bezt->vec[1], data.cut_loc);
 
-              /* Copy all control points after the cut to the new memory. */
-              memcpy(bezt1 + index + 1, nu->bezt + index, (nu->pntsu - index) * sizeof(BezTriple));
+              if (index < nu->pntsu) {
+                /* Copy all control points after the cut to the new memory. */
+                memcpy(
+                    bezt1 + index + 1, nu->bezt + index, (nu->pntsu - index) * sizeof(BezTriple));
+              }
+
               nu->pntsu += 1;
               cu->actvert = CU_ACT_NONE;
 
+              BezTriple *next_bezt;
+              if ((nu->flagu & CU_NURB_CYCLIC) && (index == nu->pntsu - 1)) {
+                next_bezt = bezt1;
+              }
+              else {
+                next_bezt = new_bezt + 1;
+              }
+
               calculate_new_bezier_point((new_bezt - 1)->vec[1],
                                          (new_bezt - 1)->vec[2],
                                          new_bezt->vec[0],
                                          new_bezt->vec[2],
-                                         (new_bezt + 1)->vec[0],
-                                         (new_bezt + 1)->vec[1],
+                                         next_bezt->vec[0],
+                                         next_bezt->vec[1],
                                          data.parameter);
 
               MEM_freeN(nu->bezt);



More information about the Bf-blender-cvs mailing list