[Bf-blender-cvs] [16b65ce31a2] soc-2021-curve-fillet: Improved limit radius behavior in curve fillet

dilithjay noreply at git.blender.org
Mon Aug 2 19:53:49 CEST 2021


Commit: 16b65ce31a226ef539c70819d214fd40414d5eb9
Author: dilithjay
Date:   Mon Aug 2 22:32:24 2021 +0530
Branches: soc-2021-curve-fillet
https://developer.blender.org/rB16b65ce31a226ef539c70819d214fd40414d5eb9

Improved limit radius behavior in curve fillet

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

M	source/blender/nodes/geometry/nodes/node_geo_curve_fillet.cc

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

diff --git a/source/blender/nodes/geometry/nodes/node_geo_curve_fillet.cc b/source/blender/nodes/geometry/nodes/node_geo_curve_fillet.cc
index eddd080f293..8f8a7a12b04 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_curve_fillet.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_curve_fillet.cc
@@ -153,80 +153,85 @@ static FilletData calculate_fillet_data_per_vertex(const float3 prev_pos,
   cross_v3_v3v3(fd.axis, vec_pos2prev, vec_pos2next);
   fd.angle = M_PI - angle_v3v3v3(prev_pos, pos, next_pos);
   fd.count = count.has_value() ? count.value() : fd.angle / arc_angle.value();
-  if (limit_radius) {
-    float max_radius = min_ff(len_v3v3(pos, prev_pos), len_v3v3(pos, next_pos)) /
-                       tanf(fd.angle / 2);
-    fd.radius = min_ff(radius, max_radius);
-  }
-  else {
-    fd.radius = radius;
-  }
+  fd.radius = radius;
 
   return fd;
 }
 
-static void limit_radii(Array<FilletData> &fds, const int size, const bool cyclic)
+/* Limit the radius based on angle and radii to prevent overlap. */
+static void limit_radii(Array<FilletData> &fds,
+                        const Span<float3> &positions,
+                        const int size,
+                        const bool cyclic)
 {
-  int fillet_count, start = 0, radii_calc_count = 0;
+  int fillet_count, start = 0;
   Array<float> max_radii(size, {-1});
 
   /* Handle the corner cases if cyclic. */
   if (cyclic) {
     fillet_count = size;
-    radii_calc_count = fillet_count - 2;
 
-    float len_prev, tan_len, tan_len_prev, max_radius_prev;
+    float len_prev, len_next, tan_len, tan_len_prev, tan_len_next;
 
+    /* Calculate lengths between adjacent control points. */
     len_prev = len_v3v3(fds[0].pos, fds[size - 1].pos);
+    len_next = len_v3v3(fds[0].pos, fds[1].pos);
+
+    /* Calculate tangent lengths of fillets in control points. */
     tan_len = fds[0].radius * tanf(fds[0].angle / 2);
     tan_len_prev = fds[size - 1].radius * tanf(fds[size - 1].angle / 2);
+    tan_len_next = fds[1].radius * tanf(fds[1].angle / 2);
 
     max_radii[0] = fds[0].radius;
+    max_radii[1] = fds[1].radius;
     max_radii[size - 1] = fds[size - 1].radius;
 
+    float factor_prev = 1, factor_next = 1;
     if (tan_len + tan_len_prev > len_prev) {
-      float factor = len_prev / (tan_len + tan_len_prev);
-      max_radii[0] *= factor;
-      max_radii[size - 1] *= factor;
+      factor_prev = len_prev / (tan_len + tan_len_prev);
+    }
+    if (tan_len + tan_len_next > len_next) {
+      factor_next = len_next / (tan_len + tan_len_next);
     }
+
+    /* Scale max radii by calculated factors. */
+    max_radii[0] *= min_ff(factor_next, factor_prev);
+    max_radii[1] *= factor_next;
+    max_radii[size - 1] *= factor_prev;
   }
   else {
     fillet_count = size - 2;
-    radii_calc_count = fillet_count - 1;
     start = 1;
   }
 
-  /* Max radii calculations of the remaining indices. */
-  for (const int i : IndexRange(start, fillet_count - 1)) {
-    int fillet_i = i - start;
-    float len = len_v3v3(fds[fillet_i].pos, fds[fillet_i + 1].pos);
-    float tan_len_1 = fds[fillet_i].radius * tanf(fds[fillet_i].angle / 2);
-    float tan_len_2 = fds[fillet_i + 1].radius * tanf(fds[fillet_i + 1].angle / 2);
-
-    if (max_radii[i] < 0) {
-      max_radii[i] = fds[fillet_i].radius;
-    }
-    else {
-      max_radii[i] = min_ff(max_radii[i], fds[fillet_i].radius);
+  /* Initialize max_radii to largest possible radii. */
+  for (const int i : IndexRange(start, fillet_count)) {
+    if (i > 0 && i < size - 1) {
+      max_radii[i] = min_ff(len_v3v3(positions[i], positions[i - 1]),
+                            len_v3v3(positions[i], positions[i + 1])) /
+                     tanf(fds[i - start].angle / 2);
     }
+  }
 
-    if (max_radii[i + 1] < 0) {
-      max_radii[i + 1] = fds[fillet_i + 1].radius;
-    }
-    else {
-      max_radii[i + 1] = min_ff(max_radii[i + 1], fds[fillet_i + 1].radius);
-    }
-    if (tan_len_1 + tan_len_2 > len) {
-      float factor = len / (tan_len_1 + tan_len_2);
-      max_radii[i] *= factor;
-      max_radii[i + 1] *= factor;
+  /* Max radii calculations for each index. */
+  for (const int i : IndexRange(start, fillet_count - 1)) {
+    int fillet_i = i - start;
+    float len_next = len_v3v3(fds[fillet_i].pos, fds[fillet_i + 1].pos);
+    float tan_len = fds[fillet_i].radius * tanf(fds[fillet_i].angle / 2);
+    float tan_len_next = fds[fillet_i + 1].radius * tanf(fds[fillet_i + 1].angle / 2);
+
+    /* Scale down radii if too large for segment. */
+    float factor = 1;
+    if (tan_len + tan_len_next > len_next) {
+      factor = len_next / (tan_len + tan_len_next);
     }
+    max_radii[i] = min_ff(max_radii[i], fds[fillet_i].radius * factor);
+    max_radii[i + 1] = min_ff(max_radii[i + 1], fds[fillet_i + 1].radius * factor);
   }
 
-  /* Divide each max_radius by tan of angle/2 because the current lengths are the lengths of
-   * tangents. */
+  /* Assign the max_radii to the fillet data's radii. */
   for (const int i : IndexRange(fillet_count)) {
-    fds[i].radius = min_ff(fds[i].radius, max_radii[start + i]);
+    fds[i].radius = max_radii[start + i];
   }
 }
 
@@ -552,7 +557,7 @@ static SplinePtr fillet_spline(const Spline &spline, const FilletModeParam &mode
   Array<FilletData> fds = calculate_fillet_data(
       src_spline_ptr, mode_param, added_count, point_counts);
   if (mode_param.limit_radius) {
-    limit_radii(fds, spline.size(), cyclic);
+    limit_radii(fds, spline.positions(), spline.size(), cyclic);
   }
 
   int total_points = added_count + size;



More information about the Bf-blender-cvs mailing list