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.
This commit is contained in:
parent
026de343e3
commit
f3eecfe386
Notes:
blender-bot
2023-02-14 05:50:03 +01:00
Referenced by issue #89430, Instanced curves arent realised after point instance Referenced by issue #89344, Join curve attributes when realizing instances
|
@ -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;
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
@ -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()) {
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue