[Bf-blender-cvs] [231948f33f8] master: Splines: Add a method for reversing a Spline

Johnny Matthews noreply at git.blender.org
Wed Sep 15 20:57:57 CEST 2021


Commit: 231948f33f8f3e79f7ae38ab9b3db3e597f13b4a
Author: Johnny Matthews
Date:   Wed Sep 15 13:57:01 2021 -0500
Branches: master
https://developer.blender.org/rB231948f33f8f3e79f7ae38ab9b3db3e597f13b4a

Splines: Add a method for reversing a Spline

This moved the spline reversing logic out of the Curve Reverse geometry
node and into the spline class. This allows a spline to reverse itself
with a call to `my_spline.reverse()`

The base class will reverse position, radii & tilt, while specialized
versions are created for Bezier and Nurbs splines to reverse the
additional data that these classes encapsulate.

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

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

M	source/blender/blenkernel/BKE_spline.hh
M	source/blender/blenkernel/intern/spline_base.cc
M	source/blender/blenkernel/intern/spline_bezier.cc
M	source/blender/blenkernel/intern/spline_nurbs.cc
M	source/blender/blenkernel/intern/spline_poly.cc
M	source/blender/nodes/geometry/nodes/node_geo_curve_reverse.cc

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

diff --git a/source/blender/blenkernel/BKE_spline.hh b/source/blender/blenkernel/BKE_spline.hh
index fc145f1ddf1..0fbf39a52fa 100644
--- a/source/blender/blenkernel/BKE_spline.hh
+++ b/source/blender/blenkernel/BKE_spline.hh
@@ -130,6 +130,11 @@ class Spline {
   virtual void translate(const blender::float3 &translation);
   virtual void transform(const blender::float4x4 &matrix);
 
+  /**
+   * Change the direction of the spline (switch the start and end) without changing its shape.
+   */
+  void reverse();
+
   /**
    * Mark all caches for re-computation. This must be called after any operation that would
    * change the generated positions, tangents, normals, mapping, etc. of the evaluated points.
@@ -210,6 +215,7 @@ class Spline {
   virtual void correct_end_tangents() const = 0;
   virtual void copy_settings(Spline &dst) const = 0;
   virtual void copy_data(Spline &dst) const = 0;
+  virtual void reverse_impl() = 0;
 };
 
 /**
@@ -353,6 +359,9 @@ class BezierSpline final : public Spline {
   void correct_end_tangents() const final;
   void copy_settings(Spline &dst) const final;
   void copy_data(Spline &dst) const final;
+
+ protected:
+  void reverse_impl() override;
 };
 
 /**
@@ -469,6 +478,7 @@ class NURBSpline final : public Spline {
   void correct_end_tangents() const final;
   void copy_settings(Spline &dst) const final;
   void copy_data(Spline &dst) const final;
+  void reverse_impl() override;
 
   void calculate_knots() const;
   blender::Span<BasisCache> calculate_basis_cache() const;
@@ -519,6 +529,7 @@ class PolySpline final : public Spline {
   void correct_end_tangents() const final;
   void copy_settings(Spline &dst) const final;
   void copy_data(Spline &dst) const final;
+  void reverse_impl() override;
 };
 
 /**
diff --git a/source/blender/blenkernel/intern/spline_base.cc b/source/blender/blenkernel/intern/spline_base.cc
index 732fabc6582..a8871777420 100644
--- a/source/blender/blenkernel/intern/spline_base.cc
+++ b/source/blender/blenkernel/intern/spline_base.cc
@@ -19,6 +19,8 @@
 #include "BLI_task.hh"
 #include "BLI_timeit.hh"
 
+#include "BKE_attribute_access.hh"
+#include "BKE_attribute_math.hh"
 #include "BKE_spline.hh"
 
 #include "FN_generic_virtual_array.hh"
@@ -28,6 +30,8 @@ using blender::float3;
 using blender::IndexRange;
 using blender::MutableSpan;
 using blender::Span;
+using blender::attribute_math::convert_to_static_type;
+using blender::bke::AttributeIDRef;
 using blender::fn::GMutableSpan;
 using blender::fn::GSpan;
 using blender::fn::GVArray;
@@ -110,6 +114,31 @@ void Spline::transform(const blender::float4x4 &matrix)
   this->mark_cache_invalid();
 }
 
+void Spline::reverse()
+{
+  this->positions().reverse();
+  this->radii().reverse();
+  this->tilts().reverse();
+
+  this->attributes.foreach_attribute(
+      [&](const AttributeIDRef &id, const AttributeMetaData &meta_data) {
+        std::optional<blender::fn::GMutableSpan> attribute = this->attributes.get_for_write(id);
+        if (!attribute) {
+          BLI_assert_unreachable();
+          return false;
+        }
+        convert_to_static_type(meta_data.data_type, [&](auto dummy) {
+          using T = decltype(dummy);
+          attribute->typed<T>().reverse();
+        });
+        return true;
+      },
+      ATTR_DOMAIN_POINT);
+
+  this->reverse_impl();
+  this->mark_cache_invalid();
+}
+
 int Spline::evaluated_edges_size() const
 {
   const int eval_size = this->evaluated_points_size();
diff --git a/source/blender/blenkernel/intern/spline_bezier.cc b/source/blender/blenkernel/intern/spline_bezier.cc
index b6764f65631..79d2137ee84 100644
--- a/source/blender/blenkernel/intern/spline_bezier.cc
+++ b/source/blender/blenkernel/intern/spline_bezier.cc
@@ -166,6 +166,17 @@ MutableSpan<float3> BezierSpline::handle_positions_right()
   return handle_positions_right_;
 }
 
+void BezierSpline::reverse_impl()
+{
+  this->handle_positions_left().reverse();
+  this->handle_positions_right().reverse();
+  std::swap(this->handle_positions_left_, this->handle_positions_right_);
+
+  this->handle_types_left().reverse();
+  this->handle_types_right().reverse();
+  std::swap(this->handle_types_left_, this->handle_types_right_);
+}
+
 static float3 previous_position(Span<float3> positions, const bool cyclic, const int i)
 {
   if (i == 0) {
diff --git a/source/blender/blenkernel/intern/spline_nurbs.cc b/source/blender/blenkernel/intern/spline_nurbs.cc
index ac6f1bd082c..6d30d8ba916 100644
--- a/source/blender/blenkernel/intern/spline_nurbs.cc
+++ b/source/blender/blenkernel/intern/spline_nurbs.cc
@@ -142,6 +142,11 @@ Span<float> NURBSpline::weights() const
   return weights_;
 }
 
+void NURBSpline::reverse_impl()
+{
+  this->weights().reverse();
+}
+
 void NURBSpline::mark_cache_invalid()
 {
   basis_cache_dirty_ = true;
diff --git a/source/blender/blenkernel/intern/spline_poly.cc b/source/blender/blenkernel/intern/spline_poly.cc
index dfd24b2566e..338b5d0ac9e 100644
--- a/source/blender/blenkernel/intern/spline_poly.cc
+++ b/source/blender/blenkernel/intern/spline_poly.cc
@@ -91,6 +91,10 @@ Span<float> PolySpline::tilts() const
   return tilts_;
 }
 
+void PolySpline::reverse_impl()
+{
+}
+
 void PolySpline::mark_cache_invalid()
 {
   tangent_cache_dirty_ = true;
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 70bb9bd28f4..32bcbe2c608 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_curve_reverse.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_curve_reverse.cc
@@ -49,47 +49,9 @@ static void geo_node_curve_reverse_exec(GeoNodeExecParams params)
 
   threading::parallel_for(splines.index_range(), 128, [&](IndexRange range) {
     for (const int i : range) {
-      if (!selection[i]) {
-        continue;
+      if (selection[i]) {
+        splines[i]->reverse();
       }
-
-      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) {
-            std::optional<blender::fn::GMutableSpan> output_attribute =
-                splines[i]->attributes.get_for_write(attribute_id);
-            if (!output_attribute) {
-              BLI_assert_unreachable();
-              return false;
-            }
-            attribute_math::convert_to_static_type(meta_data.data_type, [&](auto dummy) {
-              using T = decltype(dummy);
-              output_attribute->typed<T>().reverse();
-            });
-            return true;
-          },
-          ATTR_DOMAIN_POINT);
-
-      /* Deal with extra info on derived types. */
-      if (BezierSpline *spline = dynamic_cast<BezierSpline *>(splines[i].get())) {
-        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())) {
-        spline->weights().reverse();
-      }
-      /* Nothing to do for poly splines. */
-
-      splines[i]->mark_cache_invalid();
     }
   });



More information about the Bf-blender-cvs mailing list