From f3eecfe386098cf0a18df7ff4d8ffda9a43e9495 Mon Sep 17 00:00:00 2001 From: Hans Goudey Date: Tue, 22 Jun 2021 11:32:50 -0500 Subject: 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. --- source/blender/blenkernel/BKE_spline.hh | 32 ++++++------- source/blender/blenkernel/intern/spline_base.cc | 54 ++++++++++++++++++++++ source/blender/blenkernel/intern/spline_bezier.cc | 19 +++++--- source/blender/blenkernel/intern/spline_nurbs.cc | 22 +++++---- source/blender/blenkernel/intern/spline_poly.cc | 13 +++--- .../geometry/nodes/node_geo_curve_subdivide.cc | 2 +- .../geometry/nodes/node_geo_delete_geometry.cc | 2 +- 7 files changed, 104 insertions(+), 40 deletions(-) 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 calculate_basis_cache() const; }; @@ -473,8 +473,6 @@ class PolySpline final : public Spline { blender::Vector 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(); + case Spline::Type::Bezier: + return std::make_unique(); + case Spline::Type::NURBS: + return std::make_unique(); + } + 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(*this); + BezierSpline &bezier = static_cast(dst); + bezier.resolution_ = resolution_; } -SplinePtr BezierSpline::copy_settings() const +void BezierSpline::copy_data(Spline &dst) const { - std::unique_ptr copy = std::make_unique(); - copy_base_settings(*this, *copy); - copy->resolution_ = resolution_; - return copy; + BezierSpline &bezier = static_cast(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(*this); + NURBSpline &nurbs = static_cast(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 copy = std::make_unique(); - copy_base_settings(*this, *copy); - copy->knots_mode = knots_mode; - copy->resolution_ = resolution_; - copy->order_ = order_; - return copy; + NURBSpline &nurbs = static_cast(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(*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 copy = std::make_unique(); - copy_base_settings(*this, *copy); - return copy; + PolySpline &poly = static_cast(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 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); -- cgit v1.2.3