[Bf-blender-cvs] [a6adb7ecaef] master: BLI: Add a reverse method to MutableSpan

Johnny Matthews noreply at git.blender.org
Wed Sep 15 18:13:51 CEST 2021


Commit: a6adb7ecaef38e419d9268074193942669be6e7f
Author: Johnny Matthews
Date:   Wed Sep 15 11:13:10 2021 -0500
Branches: master
https://developer.blender.org/rBa6adb7ecaef38e419d9268074193942669be6e7f

BLI: Add a reverse method to MutableSpan

Add a method that allows a MutableSpan to reverse itself. This reverses
the data in the original span object. This is a first step in extracting
some functionality from nodes and making it more general.

Differential Revision: https://developer.blender.org/D12485

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

M	source/blender/blenlib/BLI_span.hh
M	source/blender/blenlib/tests/BLI_span_test.cc
M	source/blender/nodes/geometry/nodes/node_geo_curve_reverse.cc

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

diff --git a/source/blender/blenlib/BLI_span.hh b/source/blender/blenlib/BLI_span.hh
index e04295b0e51..5adb47ba0b0 100644
--- a/source/blender/blenlib/BLI_span.hh
+++ b/source/blender/blenlib/BLI_span.hh
@@ -643,6 +643,16 @@ template<typename T> class MutableSpan {
     return MutableSpan(data_ + size_ - new_size, new_size);
   }
 
+  /**
+   * Reverse the data in the MutableSpan.
+   */
+  constexpr void reverse()
+  {
+    for (const int i : IndexRange(size_ / 2)) {
+      std::swap(data_[size_ - 1 - i], data_[i]);
+    }
+  }
+
   /**
    * Returns an (immutable) Span that references the same array. This is usually not needed,
    * due to implicit conversions. However, sometimes automatic type deduction needs some help.
diff --git a/source/blender/blenlib/tests/BLI_span_test.cc b/source/blender/blenlib/tests/BLI_span_test.cc
index 4d23a53c08a..fb88fb63e53 100644
--- a/source/blender/blenlib/tests/BLI_span_test.cc
+++ b/source/blender/blenlib/tests/BLI_span_test.cc
@@ -362,6 +362,29 @@ TEST(span, ReverseIterator)
   EXPECT_EQ_ARRAY(reversed_vec.data(), Span({7, 6, 5, 4}).data(), 4);
 }
 
+TEST(span, ReverseMutableSpan)
+{
+  std::array<int, 0> src0 = {};
+  MutableSpan<int> span0 = src0;
+  span0.reverse();
+  EXPECT_EQ_ARRAY(span0.data(), Span<int>({}).data(), 0);
+
+  std::array<int, 1> src1 = {4};
+  MutableSpan<int> span1 = src1;
+  span1.reverse();
+  EXPECT_EQ_ARRAY(span1.data(), Span<int>({4}).data(), 1);
+
+  std::array<int, 2> src2 = {4, 5};
+  MutableSpan<int> span2 = src2;
+  span2.reverse();
+  EXPECT_EQ_ARRAY(span2.data(), Span<int>({5, 4}).data(), 2);
+
+  std::array<int, 5> src5 = {4, 5, 6, 7, 8};
+  MutableSpan<int> span5 = src5;
+  span5.reverse();
+  EXPECT_EQ_ARRAY(span5.data(), Span<int>({8, 7, 6, 5, 4}).data(), 5);
+}
+
 TEST(span, MutableReverseIterator)
 {
   std::array<int, 4> src = {4, 5, 6, 7};
diff --git a/source/blender/nodes/geometry/nodes/node_geo_curve_reverse.cc b/source/blender/nodes/geometry/nodes/node_geo_curve_reverse.cc
index 2cb75eda202..70bb9bd28f4 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_curve_reverse.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_curve_reverse.cc
@@ -29,31 +29,6 @@ static void geo_node_curve_reverse_declare(NodeDeclarationBuilder &b)
   b.add_output<decl::Geometry>("Curve");
 }
 
-/**
- * Reverse the data in a MutableSpan object.
- */
-template<typename T> static void reverse_data(MutableSpan<T> r_data)
-{
-  const int size = r_data.size();
-  for (const int i : IndexRange(size / 2)) {
-    std::swap(r_data[size - 1 - i], r_data[i]);
-  }
-}
-
-/**
- * Reverse and Swap the data between 2 MutableSpans.
- */
-template<typename T> static void reverse_data(MutableSpan<T> left, MutableSpan<T> right)
-{
-  BLI_assert(left.size() == right.size());
-  const int size = left.size();
-
-  for (const int i : IndexRange(size / 2 + size % 2)) {
-    std::swap(left[i], right[size - 1 - i]);
-    std::swap(right[i], left[size - 1 - i]);
-  }
-}
-
 static void geo_node_curve_reverse_exec(GeoNodeExecParams params)
 {
   GeometrySet geometry_set = params.extract_input<GeometrySet>("Curve");
@@ -78,9 +53,9 @@ static void geo_node_curve_reverse_exec(GeoNodeExecParams params)
         continue;
       }
 
-      reverse_data<float3>(splines[i]->positions());
-      reverse_data<float>(splines[i]->radii());
-      reverse_data<float>(splines[i]->tilts());
+      splines[i]->positions().reverse();
+      splines[i]->radii().reverse();
+      splines[i]->tilts().reverse();
 
       splines[i]->attributes.foreach_attribute(
           [&](const AttributeIDRef &attribute_id, const AttributeMetaData &meta_data) {
@@ -92,7 +67,7 @@ static void geo_node_curve_reverse_exec(GeoNodeExecParams params)
             }
             attribute_math::convert_to_static_type(meta_data.data_type, [&](auto dummy) {
               using T = decltype(dummy);
-              reverse_data(output_attribute->typed<T>());
+              output_attribute->typed<T>().reverse();
             });
             return true;
           },
@@ -100,12 +75,17 @@ static void geo_node_curve_reverse_exec(GeoNodeExecParams params)
 
       /* Deal with extra info on derived types. */
       if (BezierSpline *spline = dynamic_cast<BezierSpline *>(splines[i].get())) {
-        reverse_data<BezierSpline::HandleType>(spline->handle_types_left());
-        reverse_data<BezierSpline::HandleType>(spline->handle_types_right());
-        reverse_data<float3>(spline->handle_positions_left(), spline->handle_positions_right());
+        spline->handle_types_left().reverse();
+        spline->handle_types_right().reverse();
+
+        spline->handle_positions_left().reverse();
+        spline->handle_positions_right().reverse();
+        for (int i : spline->handle_positions_left().index_range()) {
+          std::swap(spline->handle_positions_left()[i], spline->handle_positions_right()[i]);
+        }
       }
       else if (NURBSpline *spline = dynamic_cast<NURBSpline *>(splines[i].get())) {
-        reverse_data<float>(spline->weights());
+        spline->weights().reverse();
       }
       /* Nothing to do for poly splines. */



More information about the Bf-blender-cvs mailing list