Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/blenkernel/BKE_spline.hh')
-rw-r--r--source/blender/blenkernel/BKE_spline.hh85
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);