diff options
Diffstat (limited to 'source/blender/blenkernel/BKE_spline.hh')
-rw-r--r-- | source/blender/blenkernel/BKE_spline.hh | 85 |
1 files changed, 62 insertions, 23 deletions
diff --git a/source/blender/blenkernel/BKE_spline.hh b/source/blender/blenkernel/BKE_spline.hh index 098abf6de65..9e5552082af 100644 --- a/source/blender/blenkernel/BKE_spline.hh +++ b/source/blender/blenkernel/BKE_spline.hh @@ -28,6 +28,7 @@ #include "BLI_float4x4.hh" #include "BLI_vector.hh" +#include "BKE_attribute_access.hh" #include "BKE_attribute_math.hh" struct Curve; @@ -48,10 +49,12 @@ using SplinePtr = std::unique_ptr<Spline>; * evaluation happens in a layer on top of the evaluated points generated by the derived types. * * There are a few methods to evaluate a spline: - * 1. #evaluated_positions and #interpolate_to_evaluated_points give data at the initial + * 1. #evaluated_positions and #interpolate_to_evaluated_points give data for the initial * evaluated points, depending on the resolution. * 2. #lookup_evaluated_factor and #lookup_evaluated_factor are meant for one-off lookups * along the length of a curve. + * 3. #sample_uniform_index_factors returns an array that stores uniform-length samples + * along the spline which can be used to interpolate data from method 1. * * Commonly used evaluated data is stored in caches on the spline itself so that operations on * splines don't need to worry about taking ownership of evaluated data when they don't need to. @@ -64,11 +67,6 @@ class Spline { Poly, }; - protected: - Type type_; - bool is_cyclic_ = false; - - public: enum NormalCalculationMode { ZUp, Minimum, @@ -77,7 +75,12 @@ class Spline { /* Only #Zup is supported at the moment. */ NormalCalculationMode normal_mode; + blender::bke::CustomDataAttributes attributes; + protected: + Type type_; + bool is_cyclic_ = false; + /** Direction of the spline at each evaluated point. */ mutable blender::Vector<blender::float3> evaluated_tangents_cache_; mutable std::mutex tangent_cache_mutex_; @@ -99,7 +102,10 @@ class Spline { { } Spline(Spline &other) - : type_(other.type_), is_cyclic_(other.is_cyclic_), normal_mode(other.normal_mode) + : normal_mode(other.normal_mode), + attributes(other.attributes), + type_(other.type_), + is_cyclic_(other.is_cyclic_) { } @@ -113,6 +119,7 @@ class Spline { bool is_cyclic() const; void set_cyclic(const bool value); + virtual void resize(const int size) = 0; virtual blender::MutableSpan<blender::float3> positions() = 0; virtual blender::Span<blender::float3> positions() const = 0; virtual blender::MutableSpan<float> radii() = 0; @@ -163,6 +170,9 @@ class Spline { LookupResult lookup_evaluated_factor(const float factor) const; LookupResult lookup_evaluated_length(const float length) const; + blender::Array<float> sample_uniform_index_factors(const int samples_size) const; + LookupResult lookup_data_from_index_factor(const float index_factor) const; + /** * Interpolate a virtual array of data with the size of the number of control points to the * evaluated points. For poly splines, the lifetime of the returned virtual array must not @@ -194,15 +204,21 @@ class BezierSpline final : public Spline { }; private: - blender::Vector<HandleType> handle_types_left_; - blender::Vector<blender::float3> handle_positions_left_; blender::Vector<blender::float3> positions_; - blender::Vector<HandleType> handle_types_right_; - blender::Vector<blender::float3> handle_positions_right_; blender::Vector<float> radii_; blender::Vector<float> tilts_; int resolution_; + blender::Vector<HandleType> handle_types_left_; + blender::Vector<HandleType> handle_types_right_; + + /* These are mutable to allow lazy recalculation of #Auto and #Vector handle positions. */ + mutable blender::Vector<blender::float3> handle_positions_left_; + mutable blender::Vector<blender::float3> handle_positions_right_; + + mutable std::mutex auto_handle_mutex_; + mutable bool auto_handles_dirty_ = true; + /** Start index in evaluated points array for every control point. */ mutable blender::Vector<int> offset_cache_; mutable std::mutex offset_cache_mutex_; @@ -225,14 +241,14 @@ class BezierSpline final : public Spline { } BezierSpline(const BezierSpline &other) : Spline((Spline &)other), - handle_types_left_(other.handle_types_left_), - handle_positions_left_(other.handle_positions_left_), positions_(other.positions_), - handle_types_right_(other.handle_types_right_), - handle_positions_right_(other.handle_positions_right_), radii_(other.radii_), tilts_(other.tilts_), - resolution_(other.resolution_) + resolution_(other.resolution_), + handle_types_left_(other.handle_types_left_), + handle_types_right_(other.handle_types_right_), + handle_positions_left_(other.handle_positions_left_), + handle_positions_right_(other.handle_positions_right_) { } @@ -248,6 +264,7 @@ class BezierSpline final : public Spline { const float radius, const float tilt); + void resize(const int size) final; blender::MutableSpan<blender::float3> positions() final; blender::Span<blender::float3> positions() const final; blender::MutableSpan<float> radii() final; @@ -279,22 +296,22 @@ class BezierSpline final : public Spline { int next_control_point_index; /** * Linear interpolation weight between the two indices, from 0 to 1. - * Higher means next control point. + * Higher means closer to next control point. */ float factor; }; InterpolationData interpolation_data_from_index_factor(const float index_factor) const; virtual blender::fn::GVArrayPtr interpolate_to_evaluated_points( - const blender::fn::GVArray &source_data) const; + const blender::fn::GVArray &source_data) const override; private: + void ensure_auto_handles() const; void correct_end_tangents() const final; bool segment_is_vector(const int start_index) const; void evaluate_bezier_segment(const int index, const int next_index, blender::MutableSpan<blender::float3> positions) const; - blender::Array<int> evaluated_point_offsets() const; }; /** @@ -310,6 +327,8 @@ class NURBSpline final : public Spline { EndPoint, Bezier, }; + + /** Method used to recalculate the knots vector when points are added or removed. */ KnotsMode knots_mode; struct BasisCache { @@ -387,6 +406,7 @@ class NURBSpline final : public Spline { bool check_valid_size_and_order() const; int knots_size() const; + void resize(const int size) final; blender::MutableSpan<blender::float3> positions() final; blender::Span<blender::float3> positions() const final; blender::MutableSpan<float> radii() final; @@ -418,12 +438,10 @@ class NURBSpline final : public Spline { * points does not change it. */ class PolySpline final : public Spline { - public: blender::Vector<blender::float3> positions_; blender::Vector<float> radii_; blender::Vector<float> tilts_; - private: public: SplinePtr copy() const final; PolySpline() : Spline(Type::Poly) @@ -441,6 +459,7 @@ class PolySpline final : public Spline { void add_point(const blender::float3 position, const float radius, const float tilt); + void resize(const int size) final; blender::MutableSpan<blender::float3> positions() final; blender::Span<blender::float3> positions() const final; blender::MutableSpan<float> radii() final; @@ -465,14 +484,34 @@ class PolySpline final : public Spline { * more of the data is stored in the splines, but also just to be different than the name in DNA. */ class CurveEval { + private: + blender::Vector<SplinePtr> splines_; + public: - blender::Vector<SplinePtr> splines; + blender::bke::CustomDataAttributes attributes; + + CurveEval() = default; + CurveEval(const CurveEval &other) : attributes(other.attributes) + { + for (const SplinePtr &spline : other.splines()) { + this->add_spline(spline->copy()); + } + } - CurveEval *copy(); + blender::Span<SplinePtr> splines() const; + blender::MutableSpan<SplinePtr> splines(); + + void add_spline(SplinePtr spline); + void remove_splines(blender::IndexMask mask); void translate(const blender::float3 &translation); void transform(const blender::float4x4 &matrix); void bounds_min_max(blender::float3 &min, blender::float3 &max, const bool use_evaluated) const; + + blender::Array<int> control_point_offsets() const; + blender::Array<int> evaluated_point_offsets() const; + + void assert_valid_point_attributes() const; }; std::unique_ptr<CurveEval> curve_eval_from_dna_curve(const Curve &curve); |