[Bf-blender-cvs] [f3eecfe3860] master: Cleanup: Refactor spline copying functions

Hans Goudey noreply at git.blender.org
Tue Jun 22 18:32:58 CEST 2021


Commit: f3eecfe386098cf0a18df7ff4d8ffda9a43e9495
Author: Hans Goudey
Date:   Tue Jun 22 11:32:50 2021 -0500
Branches: master
https://developer.blender.org/rBf3eecfe386098cf0a18df7ff4d8ffda9a43e9495

Cleanup: Refactor spline copying functions

Make the virtual functions protected and simpler, so that the logic is
better contained in the base class's implementation. Also introduce a
`copy_without_attributes` method to be used for realizing instances.

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

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_subdivide.cc
M	source/blender/nodes/geometry/nodes/node_geo_delete_geometry.cc

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

diff --git a/source/blender/blenkernel/BKE_spline.hh b/source/blender/blenkernel/BKE_spline.hh
index 38a6d41a4d3..24b5a78e598 100644
--- a/source/blender/blenkernel/BKE_spline.hh
+++ b/source/blender/blenkernel/BKE_spline.hh
@@ -105,9 +105,9 @@ class Spline {
     copy_base_settings(other, *this);
   }
 
-  virtual SplinePtr copy() const = 0;
-  /** Return a new spline with the same type and settings like "cyclic", but without any data. */
-  virtual SplinePtr copy_settings() const = 0;
+  SplinePtr copy() const;
+  SplinePtr copy_only_settings() const;
+  SplinePtr copy_without_attributes() const;
 
   Spline::Type type() const;
 
@@ -206,12 +206,10 @@ class Spline {
 
  protected:
   virtual void correct_end_tangents() const = 0;
-  /** Copy settings stored in the base spline class. */
-  static void copy_base_settings(const Spline &src, Spline &dst)
-  {
-    dst.normal_mode = src.normal_mode;
-    dst.is_cyclic_ = src.is_cyclic_;
-  }
+  virtual void copy_settings(Spline &dst) const = 0;
+  virtual void copy_data(Spline &dst) const = 0;
+
+  static void copy_base_settings(const Spline &src, Spline &dst);
 };
 
 /**
@@ -264,8 +262,6 @@ class BezierSpline final : public Spline {
   mutable bool mapping_cache_dirty_ = true;
 
  public:
-  virtual SplinePtr copy() const final;
-  SplinePtr copy_settings() const final;
   BezierSpline() : Spline(Type::Bezier)
   {
   }
@@ -340,8 +336,11 @@ class BezierSpline final : public Spline {
   bool segment_is_vector(const int start_index) const;
 
  private:
-  void ensure_auto_handles() const;
   void correct_end_tangents() const final;
+  void copy_settings(Spline &dst) const final;
+  void copy_data(Spline &dst) const final;
+
+  void ensure_auto_handles() const;
 };
 
 /**
@@ -406,8 +405,6 @@ class NURBSpline final : public Spline {
   mutable bool position_cache_dirty_ = true;
 
  public:
-  SplinePtr copy() const final;
-  SplinePtr copy_settings() const final;
   NURBSpline() : Spline(Type::NURBS)
   {
   }
@@ -458,6 +455,9 @@ class NURBSpline final : public Spline {
 
  protected:
   void correct_end_tangents() const final;
+  void copy_settings(Spline &dst) const final;
+  void copy_data(Spline &dst) const final;
+
   void calculate_knots() const;
   blender::Span<BasisCache> calculate_basis_cache() const;
 };
@@ -473,8 +473,6 @@ class PolySpline final : public Spline {
   blender::Vector<float> tilts_;
 
  public:
-  SplinePtr copy() const final;
-  SplinePtr copy_settings() const final;
   PolySpline() : Spline(Type::Poly)
   {
   }
@@ -507,6 +505,8 @@ class PolySpline final : public Spline {
 
  protected:
   void correct_end_tangents() const final;
+  void copy_settings(Spline &dst) const final;
+  void copy_data(Spline &dst) const final;
 };
 
 /**
diff --git a/source/blender/blenkernel/intern/spline_base.cc b/source/blender/blenkernel/intern/spline_base.cc
index c18f44e07b2..aa0d95d4d61 100644
--- a/source/blender/blenkernel/intern/spline_base.cc
+++ b/source/blender/blenkernel/intern/spline_base.cc
@@ -40,6 +40,60 @@ Spline::Type Spline::type() const
   return type_;
 }
 
+void Spline::copy_base_settings(const Spline &src, Spline &dst)
+{
+  dst.normal_mode = src.normal_mode;
+  dst.is_cyclic_ = src.is_cyclic_;
+}
+
+static SplinePtr create_spline(const Spline::Type type)
+{
+  switch (type) {
+    case Spline::Type::Poly:
+      return std::make_unique<PolySpline>();
+    case Spline::Type::Bezier:
+      return std::make_unique<BezierSpline>();
+    case Spline::Type::NURBS:
+      return std::make_unique<NURBSpline>();
+  }
+  BLI_assert_unreachable();
+  return {};
+}
+
+/**
+ * Return a new spline with the same data, settings, and attributes.
+ */
+SplinePtr Spline::copy() const
+{
+  SplinePtr dst = this->copy_without_attributes();
+  dst->attributes = this->attributes;
+  return dst;
+}
+
+/**
+ * Return a new spline with the same type and settings like "cyclic", but without any data.
+ */
+SplinePtr Spline::copy_only_settings() const
+{
+  SplinePtr dst = create_spline(type_);
+  this->copy_base_settings(*this, *dst);
+  this->copy_settings(*dst);
+  return dst;
+}
+
+/**
+ * The same as #copy, but skips copying dynamic attributes to the new spline.
+ */
+SplinePtr Spline::copy_without_attributes() const
+{
+  SplinePtr dst = this->copy_only_settings();
+  this->copy_data(*dst);
+
+  /* Though the attributes storage is empty, it still needs to know the correct size. */
+  dst->attributes.reallocate(dst->size());
+  return dst;
+}
+
 void Spline::translate(const blender::float3 &translation)
 {
   for (float3 &position : this->positions()) {
diff --git a/source/blender/blenkernel/intern/spline_bezier.cc b/source/blender/blenkernel/intern/spline_bezier.cc
index daae03167ef..02d26ac715b 100644
--- a/source/blender/blenkernel/intern/spline_bezier.cc
+++ b/source/blender/blenkernel/intern/spline_bezier.cc
@@ -29,17 +29,22 @@ using blender::fn::GVArray;
 using blender::fn::GVArray_For_ArrayContainer;
 using blender::fn::GVArrayPtr;
 
-SplinePtr BezierSpline::copy() const
+void BezierSpline::copy_settings(Spline &dst) const
 {
-  return std::make_unique<BezierSpline>(*this);
+  BezierSpline &bezier = static_cast<BezierSpline &>(dst);
+  bezier.resolution_ = resolution_;
 }
 
-SplinePtr BezierSpline::copy_settings() const
+void BezierSpline::copy_data(Spline &dst) const
 {
-  std::unique_ptr<BezierSpline> copy = std::make_unique<BezierSpline>();
-  copy_base_settings(*this, *copy);
-  copy->resolution_ = resolution_;
-  return copy;
+  BezierSpline &bezier = static_cast<BezierSpline &>(dst);
+  bezier.positions_ = positions_;
+  bezier.handle_types_left_ = handle_types_left_;
+  bezier.handle_positions_left_ = handle_positions_left_;
+  bezier.handle_types_right_ = handle_types_right_;
+  bezier.handle_positions_right_ = handle_positions_right_;
+  bezier.radii_ = radii_;
+  bezier.tilts_ = tilts_;
 }
 
 int BezierSpline::size() const
diff --git a/source/blender/blenkernel/intern/spline_nurbs.cc b/source/blender/blenkernel/intern/spline_nurbs.cc
index 31ac23589be..85fb9730e83 100644
--- a/source/blender/blenkernel/intern/spline_nurbs.cc
+++ b/source/blender/blenkernel/intern/spline_nurbs.cc
@@ -31,19 +31,23 @@ using blender::fn::GVArray_For_ArrayContainer;
 using blender::fn::GVArray_Typed;
 using blender::fn::GVArrayPtr;
 
-SplinePtr NURBSpline::copy() const
+void NURBSpline::copy_settings(Spline &dst) const
 {
-  return std::make_unique<NURBSpline>(*this);
+  NURBSpline &nurbs = static_cast<NURBSpline &>(dst);
+  nurbs.knots_mode = knots_mode;
+  nurbs.resolution_ = resolution_;
+  nurbs.order_ = order_;
 }
 
-SplinePtr NURBSpline::copy_settings() const
+void NURBSpline::copy_data(Spline &dst) const
 {
-  std::unique_ptr<NURBSpline> copy = std::make_unique<NURBSpline>();
-  copy_base_settings(*this, *copy);
-  copy->knots_mode = knots_mode;
-  copy->resolution_ = resolution_;
-  copy->order_ = order_;
-  return copy;
+  NURBSpline &nurbs = static_cast<NURBSpline &>(dst);
+  nurbs.positions_ = positions_;
+  nurbs.weights_ = weights_;
+  nurbs.knots_ = knots_;
+  nurbs.knots_dirty_ = false;
+  nurbs.radii_ = radii_;
+  nurbs.tilts_ = tilts_;
 }
 
 int NURBSpline::size() const
diff --git a/source/blender/blenkernel/intern/spline_poly.cc b/source/blender/blenkernel/intern/spline_poly.cc
index e344b8d4910..dfd24b2566e 100644
--- a/source/blender/blenkernel/intern/spline_poly.cc
+++ b/source/blender/blenkernel/intern/spline_poly.cc
@@ -25,16 +25,17 @@ using blender::Span;
 using blender::fn::GVArray;
 using blender::fn::GVArrayPtr;
 
-SplinePtr PolySpline::copy() const
+void PolySpline::copy_settings(Spline &UNUSED(dst)) const
 {
-  return std::make_unique<PolySpline>(*this);
+  /* Poly splines have no settings not covered by the base class. */
 }
 
-SplinePtr PolySpline::copy_settings() const
+void PolySpline::copy_data(Spline &dst) const
 {
-  std::unique_ptr<PolySpline> copy = std::make_unique<PolySpline>();
-  copy_base_settings(*this, *copy);
-  return copy;
+  PolySpline &poly = static_cast<PolySpline &>(dst);
+  poly.positions_ = positions_;
+  poly.radii_ = radii_;
+  poly.tilts_ = tilts_;
 }
 
 int PolySpline::size() const
diff --git a/source/blender/nodes/geometry/nodes/node_geo_curve_subdivide.cc b/source/blender/nodes/geometry/nodes/node_geo_curve_subdivide.cc
index fdb01fa07cf..3de2604cd0a 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_curve_subdivide.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_curve_subdivide.cc
@@ -329,7 +329,7 @@ static SplinePtr subdivide_spline(const Spline &spline,
    * point facilitates subdividing in parallel later. */
   Array<int> offsets = get_subdivided_offsets(spline, cuts, spline_offset);
   const int result_size = offsets.last() + int(!spline.is_cyclic());
-  SplinePtr new_spline = spline.copy_settings();
+  SplinePtr new_spline = spline.copy_only_settings();
   new_spline->resize(result_size);
   subdivide_builtin_attributes(spline, offsets, *new_spline);
   subdivide_dynamic_attributes(spline, offsets, *new_spline);
diff --git a/source/blender/nodes/geometry/nodes/node_geo_delete_geometry.cc b/source/blender/nodes/geometry/nodes/node_geo_delete_geometry.cc
index 910adc467d6..b1da2dcd3c4 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_delete_geometry.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_delete_geometry.cc
@@ -120,7 +120,7 @@ static void copy_dynamic_attributes(const CustomDataAttributes &src,
 
 static SplinePtr spline_delete(const Spline &spline, const IndexMask mask)
 {
-  SplinePtr new_spline = spline.copy_settings();
+  SplinePtr new_spline = spline.copy_only_settings();
   new_spline->resize(mask.size());
 
   spline_copy_builtin_attributes(spline, *new_spline, mask);



More information about the Bf-blender-cvs mailing list