[Bf-blender-cvs] [e4d3a5518cc] soc-2021-curve-fillet: Update curve fillet code based on patch review

dilithjay noreply at git.blender.org
Tue Aug 10 19:10:48 CEST 2021


Commit: e4d3a5518cc73916c54956a9cd411beacba0aba8
Author: dilithjay
Date:   Tue Aug 10 14:19:03 2021 +0530
Branches: soc-2021-curve-fillet
https://developer.blender.org/rBe4d3a5518cc73916c54956a9cd411beacba0aba8

Update curve fillet code based on patch review

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

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 a09bb242381..8bc9cbb2914 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_curve_fillet.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_curve_fillet.cc
@@ -23,8 +23,6 @@
 
 #include "BKE_spline.hh"
 
-#include "float.h"
-
 static bNodeSocketTemplate geo_node_curve_fillet_in[] = {
     {SOCK_GEOMETRY, N_("Curve")},
     {SOCK_FLOAT, N_("Angle"), M_PI_2, 0.0f, 0.0f, 0.0f, 0.001f, FLT_MAX, PROP_ANGLE},
@@ -84,10 +82,10 @@ struct FilletModeParam {
   GVArray_Typed<float> *radii{};
 };
 
-/* A data structure used to store fillet data about a vertex in the source spline. */
+/* A data structure used to store fillet data about all vertices to be filleted. */
 struct FilletData {
-  float3 prev_dir, pos, next_dir, axis;
-  float radius, angle, count;
+  Array<float3> prev_dirs, positions, next_dirs, axes;
+  Array<float> radii, angles, counts;
 };
 
 static void geo_node_curve_fillet_update(bNodeTree *UNUSED(ntree), bNode *node)
@@ -126,64 +124,68 @@ static float3 get_center(const float3 vec_pos2prev,
 }
 
 /* Function to get the center of the fillet using fillet data */
-static float3 get_center(const float3 vec_pos2prev, const FilletData &fd)
+static float3 get_center(const float3 vec_pos2prev, const FilletData &fd, const int index)
 {
-  float angle = fd.angle;
-  float3 axis = fd.axis;
-  float3 pos = fd.pos;
+  float angle = fd.angles[index];
+  float3 axis = fd.axes[index];
+  float3 pos = fd.positions[index];
 
   return get_center(vec_pos2prev, pos, axis, angle);
 }
 
-/* Function to calculate fillet data for each vertex. */
-static FilletData calculate_fillet_data_per_vertex(const float3 prev_pos,
+/* Function to calculate fillet data for the specified index. */
+static FilletData calculate_fillet_data_per_vertex(FilletData &fd,
+                                                   const float3 prev_pos,
                                                    const float3 pos,
                                                    const float3 next_pos,
                                                    const std::optional<float> arc_angle,
                                                    const std::optional<int> count,
-                                                   const float radius)
+                                                   const float radius,
+                                                   const int index)
 {
-  FilletData fd{};
   float3 vec_pos2prev = prev_pos - pos;
   float3 vec_pos2next = next_pos - pos;
-  normalize_v3_v3(fd.prev_dir, vec_pos2prev);
-  normalize_v3_v3(fd.next_dir, vec_pos2next);
-  fd.pos = 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();
-  fd.radius = radius;
+  normalize_v3_v3(fd.prev_dirs[index], vec_pos2prev);
+  normalize_v3_v3(fd.next_dirs[index], vec_pos2next);
+  fd.positions[index] = pos;
+  cross_v3_v3v3(fd.axes[index], vec_pos2prev, vec_pos2next);
+  fd.angles[index] = M_PI - angle_v3v3v3(prev_pos, pos, next_pos);
+  fd.counts[index] = count.has_value() ? count.value() : fd.angles[index] / arc_angle.value();
+  fd.radii[index] = radius;
 
   return fd;
 }
 
 /* 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)
+static void limit_radii(FilletData &fd, const Span<float3> &spline_positions, const bool cyclic)
 {
+  MutableSpan<float> radii(fd.radii);
+  Span<float> angles(fd.angles);
+  Span<float3> axes(fd.axes);
+  Span<float3> positions(fd.positions);
+  Span<float3> prev_dirs(fd.prev_dirs);
+  Span<float3> next_dirs(fd.next_dirs);
+
+  const int size = spline_positions.size();
   int fillet_count, start = 0;
-  Array<float> max_radii(size, {-1});
+  Array<float> max_radii(size, -1.0f);
 
   /* Handle the corner cases if cyclic. */
   if (cyclic) {
     fillet_count = size;
 
-    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);
+    const float len_prev = (positions[0] - positions[size - 1]).length_squared();
+    const float len_next = (positions[0] - positions[1]).length_squared();
 
     /* 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);
+    const float tan_len = radii[0] * tanf(angles[0] / 2);
+    const float tan_len_prev = radii[size - 1] * tanf(angles[size - 1] / 2);
+    const float tan_len_next = radii[1] * tanf(angles[1] / 2);
 
-    max_radii[0] = fds[0].radius;
-    max_radii[1] = fds[1].radius;
-    max_radii[size - 1] = fds[size - 1].radius;
+    max_radii[0] = radii[0];
+    max_radii[1] = radii[1];
+    max_radii[size - 1] = radii[size - 1];
 
     float factor_prev = 1, factor_next = 1;
     if (tan_len + tan_len_prev > len_prev) {
@@ -206,57 +208,71 @@ static void limit_radii(Array<FilletData> &fds,
   /* 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);
+      max_radii[i] = min_ff(len_v3v3(spline_positions[i], spline_positions[i - 1]),
+                            len_v3v3(spline_positions[i], spline_positions[i + 1])) /
+                     tanf(angles[i - start] / 2);
     }
   }
 
   /* 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);
+    float len_next = len_v3v3(positions[fillet_i], positions[fillet_i + 1]);
+    float tan_len = radii[fillet_i] * tanf(angles[fillet_i] / 2);
+    float tan_len_next = radii[fillet_i + 1] * tanf(angles[fillet_i + 1] / 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);
+    max_radii[i] = min_ff(max_radii[i], radii[fillet_i] * factor);
+    max_radii[i + 1] = min_ff(max_radii[i + 1], radii[fillet_i + 1] * factor);
   }
 
   /* Assign the max_radii to the fillet data's radii. */
   for (const int i : IndexRange(fillet_count)) {
-    fds[i].radius = max_radii[start + i];
+    radii[i] = max_radii[start + i];
   }
 }
 
+/* Initialize FilletData data structure with Arrays of specified length. */
+static void init_fillet_data(FilletData &fd, const int fillet_count)
+{
+  fd.prev_dirs = Array<float3>(fillet_count);
+  fd.positions = Array<float3>(fillet_count);
+  fd.next_dirs = Array<float3>(fillet_count);
+  fd.axes = Array<float3>(fillet_count);
+  fd.radii = Array<float>(fillet_count);
+  fd.angles = Array<float>(fillet_count);
+  fd.counts = Array<float>(fillet_count);
+}
+
 /* Function to calculate and obtain the fillet data for the entire spline. */
-static Array<FilletData> calculate_fillet_data(const SplinePtr &spline,
-                                               const FilletModeParam &mode_param,
-                                               int &added_count,
-                                               Array<int> &point_counts,
-                                               const int spline_index)
+static FilletData calculate_fillet_data(const Spline &spline,
+                                        const FilletModeParam &mode_param,
+                                        int &added_count,
+                                        MutableSpan<int> point_counts,
+                                        const int spline_index)
 {
-  Span<float3> positions = spline->positions();
-  int fillet_count, start = 0, size = spline->size();
+  Span<float3> positions = spline.positions();
+  int fillet_count, start = 0;
+  const int size = spline.size();
 
   /* Determine the number of vertices that can be filleted. */
-  bool cyclic = spline->is_cyclic();
-  if (!cyclic) {
-    fillet_count = size - 2;
-    start = 1;
+  const bool cyclic = spline.is_cyclic();
+  if (cyclic) {
+    fillet_count = size;
   }
   else {
-    fillet_count = size;
+    fillet_count = size - 2;
+    start = 1;
   }
 
-  Array<FilletData> fds(fillet_count);
+  FilletData fd;
+  init_fillet_data(fd, fillet_count);
 
-  for (const int i : IndexRange(fillet_count)) {
+  for (const int i : IndexRange(start, fillet_count)) {
     /* Find the positions of the adjacent vertices. */
     float3 prev_pos, pos, next_pos;
     if (cyclic) {
@@ -265,9 +281,9 @@ static Array<FilletData> calculate_fillet_data(const SplinePtr &spline,
       next_pos = positions[i == positions.size() - 1 ? 0 : i + 1];
     }
     else {
-      prev_pos = positions[i];
-      pos = positions[i + 1];
-      next_pos = positions[i + 2];
+      prev_pos = positions[i - 1];
+      pos = positions[i];
+      next_pos = positions[i + 1];
     }
 
     /* Define the radius. */
@@ -276,12 +292,12 @@ static Array<FilletData> calculate_fillet_data(const SplinePtr &spline,
       radius = mode_param.radius.value();
     }
     else if (mode_param.radius_mode == GEO_NODE_CURVE_FILLET_RADIUS_ATTRIBUTE) {
-      radius = (*mode_param.radii)[spline_index + start + i];
+      radius = (*mode_param.radii)[spline_index + i];
     }


@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list