Blender  V3.3
BKE_spline.hh
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-or-later */
2 
3 #pragma once
4 
9 #include <mutex>
10 
11 #include "DNA_curves_types.h"
12 
13 #include "BLI_float4x4.hh"
15 #include "BLI_math_vec_types.hh"
16 #include "BLI_vector.hh"
17 
18 #include "BKE_attribute.hh"
19 #include "BKE_attribute_math.hh"
20 
21 struct Curve;
22 struct Curves;
23 struct ListBase;
24 
25 class Spline;
26 using SplinePtr = std::unique_ptr<Spline>;
27 
52 class Spline {
53  public:
55 
57 
58  protected:
60  bool is_cyclic_ = false;
61 
65  mutable bool tangent_cache_dirty_ = true;
66 
70  mutable bool normal_cache_dirty_ = true;
71 
75  mutable bool length_cache_dirty_ = true;
76 
77  public:
78  virtual ~Spline() = default;
80  {
81  }
82  Spline(Spline &other) : attributes(other.attributes), type_(other.type_)
83  {
84  copy_base_settings(other, *this);
85  }
86 
90  SplinePtr copy() const;
99  static void copy_base_settings(const Spline &src, Spline &dst);
100 
101  CurveType type() const;
102 
104  virtual int size() const = 0;
105  int segments_num() const;
106  bool is_cyclic() const;
107  void set_cyclic(bool value);
108 
109  virtual void resize(int size) = 0;
113  virtual blender::Span<float> radii() const = 0;
115  virtual blender::Span<float> tilts() const = 0;
116 
117  virtual void translate(const blender::float3 &translation);
118  virtual void transform(const blender::float4x4 &matrix);
119 
123  void reverse();
124 
129  virtual void mark_cache_invalid() = 0;
130  virtual int evaluated_points_num() const = 0;
131  int evaluated_edges_num() const;
132 
133  float length() const;
134 
136 
154 
155  void bounds_min_max(blender::float3 &min, blender::float3 &max, bool use_evaluated) const;
156 
157  struct LookupResult {
174  float factor;
175  };
182  LookupResult lookup_evaluated_factor(float factor) const;
188 
195  LookupResult lookup_data_from_index_factor(float index_factor) const;
196 
203  blender::Span<float> index_factors,
204  blender::GMutableSpan dst) const;
205  template<typename T>
207  blender::Span<float> index_factors,
208  blender::MutableSpan<T> dst) const
209  {
211  blender::GVArray(src), index_factors, blender::GMutableSpan(dst));
212  }
213  template<typename T>
215  blender::Span<float> index_factors,
216  blender::MutableSpan<T> dst) const
217  {
218  this->sample_with_index_factors(blender::VArray<T>::ForSpan(src), index_factors, dst);
219  }
220 
229  {
231  }
232 
233  protected:
234  virtual void correct_end_tangents() const = 0;
235  virtual void copy_settings(Spline &dst) const = 0;
236  virtual void copy_data(Spline &dst) const = 0;
237  virtual void reverse_impl() = 0;
238 };
239 
245 class BezierSpline final : public Spline {
247  blender::Vector<float> radii_;
248  blender::Vector<float> tilts_;
249  int resolution_;
250 
251  blender::Vector<int8_t> handle_types_left_;
252  blender::Vector<int8_t> handle_types_right_;
253 
254  /* These are mutable to allow lazy recalculation of #Auto and #Vector handle positions. */
255  mutable blender::Vector<blender::float3> handle_positions_left_;
256  mutable blender::Vector<blender::float3> handle_positions_right_;
257 
258  mutable std::mutex auto_handle_mutex_;
259  mutable bool auto_handles_dirty_ = true;
260 
262  mutable blender::Vector<int> offset_cache_;
263  mutable std::mutex offset_cache_mutex_;
264  mutable bool offset_cache_dirty_ = true;
265 
267  mutable blender::Vector<blender::float3> evaluated_position_cache_;
268  mutable std::mutex position_cache_mutex_;
269  mutable bool position_cache_dirty_ = true;
270 
272  mutable blender::Vector<float> evaluated_mapping_cache_;
273  mutable std::mutex mapping_cache_mutex_;
274  mutable bool mapping_cache_dirty_ = true;
275 
276  public:
278  {
279  }
281  : Spline((Spline &)other),
282  positions_(other.positions_),
283  radii_(other.radii_),
284  tilts_(other.tilts_),
285  resolution_(other.resolution_),
286  handle_types_left_(other.handle_types_left_),
287  handle_types_right_(other.handle_types_right_),
288  handle_positions_left_(other.handle_positions_left_),
289  handle_positions_right_(other.handle_positions_right_)
290  {
291  }
292 
293  int size() const final;
294  int resolution() const;
295  void set_resolution(int value);
296 
297  void resize(int size) final;
298  blender::MutableSpan<blender::float3> positions() final;
299  blender::Span<blender::float3> positions() const final;
300  blender::MutableSpan<float> radii() final;
301  blender::Span<float> radii() const final;
302  blender::MutableSpan<float> tilts() final;
303  blender::Span<float> tilts() const final;
304  blender::Span<int8_t> handle_types_left() const;
305  blender::MutableSpan<int8_t> handle_types_left();
313  blender::MutableSpan<blender::float3> handle_positions_left(bool write_only = false);
314  blender::Span<int8_t> handle_types_right() const;
315  blender::MutableSpan<int8_t> handle_types_right();
323  blender::MutableSpan<blender::float3> handle_positions_right(bool write_only = false);
328  void ensure_auto_handles() const;
329 
330  void translate(const blender::float3 &translation) override;
331  void transform(const blender::float4x4 &matrix) override;
332 
337  void set_handle_position_right(int index, const blender::float3 &value);
342  void set_handle_position_left(int index, const blender::float3 &value);
343 
344  bool point_is_sharp(int index) const;
345 
346  void mark_cache_invalid() final;
347  int evaluated_points_num() const final;
348 
358  blender::Span<int> control_point_offsets() const;
365  blender::Span<float> evaluated_mappings() const;
374  float factor;
375  };
382 
383  virtual blender::GVArray interpolate_to_evaluated(const blender::GVArray &src) const override;
384 
385  void evaluate_segment(int index,
386  int next_index,
391  bool segment_is_vector(int start_index) const;
392 
394  struct InsertResult {
400  };
420  InsertResult calculate_segment_insertion(int index, int next_index, float parameter);
421 
422  private:
429  void correct_end_tangents() const final;
430  void copy_settings(Spline &dst) const final;
431  void copy_data(Spline &dst) const final;
432 
433  protected:
434  void reverse_impl() override;
435 };
436 
443 class NURBSpline final : public Spline {
444  public:
447 
448  struct BasisCache {
458  };
459 
460  private:
462  blender::Vector<float> radii_;
463  blender::Vector<float> tilts_;
464  blender::Vector<float> weights_;
465  int resolution_;
471  uint8_t order_;
472 
478  mutable blender::Vector<float> knots_;
479  mutable std::mutex knots_mutex_;
480  mutable bool knots_dirty_ = true;
481 
483  mutable BasisCache basis_cache_;
484  mutable std::mutex basis_cache_mutex_;
485  mutable bool basis_cache_dirty_ = true;
486 
491  mutable blender::Vector<blender::float3> evaluated_position_cache_;
492  mutable std::mutex position_cache_mutex_;
493  mutable bool position_cache_dirty_ = true;
494 
495  public:
497  {
498  }
499  NURBSpline(const NURBSpline &other)
500  : Spline((Spline &)other),
501  knots_mode(other.knots_mode),
502  positions_(other.positions_),
503  radii_(other.radii_),
504  tilts_(other.tilts_),
505  weights_(other.weights_),
506  resolution_(other.resolution_),
507  order_(other.order_)
508  {
509  }
510 
511  int size() const final;
512  int resolution() const;
513  void set_resolution(int value);
514  uint8_t order() const;
515  void set_order(uint8_t value);
516 
517  bool check_valid_num_and_order() const;
518  int knots_num() const;
519 
520  void resize(int size) final;
521  blender::MutableSpan<blender::float3> positions() final;
522  blender::Span<blender::float3> positions() const final;
523  blender::MutableSpan<float> radii() final;
524  blender::Span<float> radii() const final;
525  blender::MutableSpan<float> tilts() final;
526  blender::Span<float> tilts() const final;
527  blender::Span<float> knots() const;
528 
529  blender::MutableSpan<float> weights();
530  blender::Span<float> weights() const;
531 
532  void mark_cache_invalid() final;
533  int evaluated_points_num() const final;
534 
536 
537  blender::GVArray interpolate_to_evaluated(const blender::GVArray &src) const final;
538 
539  protected:
540  void correct_end_tangents() const final;
541  void copy_settings(Spline &dst) const final;
542  void copy_data(Spline &dst) const final;
543  void reverse_impl() override;
544 
545  void calculate_knots() const;
546  const BasisCache &calculate_basis_cache() const;
547 };
548 
557 class PolySpline final : public Spline {
559  blender::Vector<float> radii_;
560  blender::Vector<float> tilts_;
561 
562  public:
564  {
565  }
566  PolySpline(const PolySpline &other)
567  : Spline((Spline &)other),
568  positions_(other.positions_),
569  radii_(other.radii_),
570  tilts_(other.tilts_)
571  {
572  }
573 
574  int size() const final;
575 
576  void resize(int size) final;
577  blender::MutableSpan<blender::float3> positions() final;
578  blender::Span<blender::float3> positions() const final;
579  blender::MutableSpan<float> radii() final;
580  blender::Span<float> radii() const final;
581  blender::MutableSpan<float> tilts() final;
582  blender::Span<float> tilts() const final;
583 
584  void mark_cache_invalid() final;
585  int evaluated_points_num() const final;
586 
588 
595  blender::GVArray interpolate_to_evaluated(const blender::GVArray &src) const final;
596 
597  protected:
598  void correct_end_tangents() const final;
599  void copy_settings(Spline &dst) const final;
600  void copy_data(Spline &dst) const final;
601  void reverse_impl() override;
602 };
603 
612 struct CurveEval {
613  private:
615 
616  public:
618 
619  CurveEval() = default;
620  CurveEval(const CurveEval &other) : attributes(other.attributes)
621  {
622  for (const SplinePtr &spline : other.splines()) {
623  this->add_spline(spline->copy());
624  }
625  }
626 
635  bool has_spline_with_type(const CurveType type) const;
636 
637  void resize(int size);
641  void add_spline(SplinePtr spline);
642  void add_splines(blender::MutableSpan<SplinePtr> splines);
643  void remove_splines(blender::IndexMask mask);
644 
645  void translate(const blender::float3 &translation);
646  void transform(const blender::float4x4 &matrix);
647  bool bounds_min_max(blender::float3 &min, blender::float3 &max, bool use_evaluated) const;
648 
649  blender::bke::MutableAttributeAccessor attributes_for_write();
650 
662  blender::Array<int> evaluated_point_offsets() const;
667  blender::Array<float> accumulated_spline_lengths() const;
668 
669  float total_length() const;
670  int total_control_point_num() const;
671 
672  void mark_cache_invalid();
673 
681  void assert_valid_point_attributes() const;
682 };
683 
684 std::unique_ptr<CurveEval> curve_eval_from_dna_curve(const Curve &curve,
685  const ListBase &nurbs_list);
686 std::unique_ptr<CurveEval> curve_eval_from_dna_curve(const Curve &dna_curve);
687 std::unique_ptr<CurveEval> curves_to_curve_eval(const Curves &curves);
688 Curves *curve_eval_to_curves(const CurveEval &curve_eval);
std::unique_ptr< Spline > SplinePtr
Definition: BKE_spline.hh:26
std::unique_ptr< CurveEval > curve_eval_from_dna_curve(const Curve &curve, const ListBase &nurbs_list)
Definition: curve_eval.cc:303
std::unique_ptr< CurveEval > curves_to_curve_eval(const Curves &curves)
Definition: curve_eval.cc:373
Curves * curve_eval_to_curves(const CurveEval &curve_eval)
Definition: curve_eval.cc:463
#define final(a, b, c)
Definition: BLI_hash.h:21
ThreadMutex mutex
CurveType
@ CURVE_TYPE_BEZIER
@ CURVE_TYPE_NURBS
@ CURVE_TYPE_POLY
NormalMode
@ NORMAL_MODE_MINIMUM_TWIST
KnotsMode
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint GLsizei GLsizei GLenum type _GL_VOID_RET _GL_VOID GLsizei GLenum GLenum const void *pixels _GL_VOID_RET _GL_VOID const void *pointer _GL_VOID_RET _GL_VOID GLdouble v _GL_VOID_RET _GL_VOID GLfloat v _GL_VOID_RET _GL_VOID GLint GLint i2 _GL_VOID_RET _GL_VOID GLint j _GL_VOID_RET _GL_VOID GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble GLdouble GLdouble zFar _GL_VOID_RET _GL_UINT GLdouble *equation _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLenum GLfloat *v _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLfloat *values _GL_VOID_RET _GL_VOID GLushort *values _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLenum GLdouble *params _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_BOOL GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLushort pattern _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint order
float float4x4[4][4]
Group Output data from inside of a node group A color picker Mix two input colors RGB to Convert a color s luminance to a grayscale value Generate a normal vector and a dot product Bright Control the brightness and contrast of the input color Vector Map an input vectors to curves
int size() const final
blender::MutableSpan< float > tilts() final
blender::Span< blender::float3 > handle_positions_right() const
bool segment_is_vector(int start_index) const
blender::Span< float > evaluated_mappings() const
void resize(int size) final
blender::Span< blender::float3 > handle_positions_left() const
void set_handle_position_left(int index, const blender::float3 &value)
void transform(const blender::float4x4 &matrix) override
void evaluate_segment(int index, int next_index, blender::MutableSpan< blender::float3 > positions) const
InsertResult calculate_segment_insertion(int index, int next_index, float parameter)
int evaluated_points_num() const final
blender::Span< int8_t > handle_types_left() const
void ensure_auto_handles() const
InterpolationData interpolation_data_from_index_factor(float index_factor) const
blender::Span< int > control_point_offsets() const
void translate(const blender::float3 &translation) override
int resolution() const
virtual blender::GVArray interpolate_to_evaluated(const blender::GVArray &src) const override
bool point_is_sharp(int index) const
void mark_cache_invalid() final
BezierSpline(const BezierSpline &other)
Definition: BKE_spline.hh:280
void set_resolution(int value)
blender::Span< int8_t > handle_types_right() const
blender::Span< blender::float3 > evaluated_positions() const final
void set_handle_position_right(int index, const blender::float3 &value)
void reverse_impl() override
blender::MutableSpan< blender::float3 > positions() final
blender::MutableSpan< float > radii() final
KnotsMode knots_mode
Definition: BKE_spline.hh:446
NURBSpline(const NURBSpline &other)
Definition: BKE_spline.hh:499
PolySpline(const PolySpline &other)
Definition: BKE_spline.hh:566
LookupResult lookup_evaluated_factor(float factor) const
Definition: spline_base.cc:400
virtual blender::Span< float > tilts() const =0
std::mutex tangent_cache_mutex_
Definition: BKE_spline.hh:64
virtual void translate(const blender::float3 &translation)
Definition: spline_base.cc:78
virtual blender::MutableSpan< blender::float3 > positions()=0
CurveType type() const
Definition: spline_base.cc:25
std::mutex length_cache_mutex_
Definition: BKE_spline.hh:74
virtual blender::MutableSpan< float > tilts()=0
virtual void resize(int size)=0
int evaluated_edges_num() const
Definition: spline_base.cc:119
blender::Span< float > evaluated_lengths() const
Definition: spline_base.cc:169
void sample_with_index_factors(const blender::VArray< T > &src, blender::Span< float > index_factors, blender::MutableSpan< T > dst) const
Definition: BKE_spline.hh:206
SplinePtr copy_without_attributes() const
Definition: spline_base.cc:68
CurveType type_
Definition: BKE_spline.hh:59
bool tangent_cache_dirty_
Definition: BKE_spline.hh:65
blender::Array< float > sample_uniform_index_factors(int samples_num) const
Definition: spline_base.cc:423
void set_cyclic(bool value)
Definition: spline_base.cc:148
virtual void transform(const blender::float4x4 &matrix)
Definition: spline_base.cc:86
void bounds_min_max(blender::float3 &min, blender::float3 &max, bool use_evaluated) const
Definition: spline_base.cc:490
blender::Vector< blender::float3 > evaluated_tangents_cache_
Definition: BKE_spline.hh:63
SplinePtr copy() const
Definition: spline_base.cc:53
std::mutex normal_cache_mutex_
Definition: BKE_spline.hh:69
blender::Vector< float > evaluated_lengths_cache_
Definition: BKE_spline.hh:73
virtual int size() const =0
bool is_cyclic_
Definition: BKE_spline.hh:60
NormalMode normal_mode
Definition: BKE_spline.hh:54
float length() const
Definition: spline_base.cc:130
virtual int evaluated_points_num() const =0
virtual blender::Span< float > radii() const =0
LookupResult lookup_data_from_index_factor(float index_factor) const
Definition: spline_base.cc:469
virtual void reverse_impl()=0
blender::Vector< blender::float3 > evaluated_normals_cache_
Definition: BKE_spline.hh:68
blender::VArray< T > interpolate_to_evaluated(blender::Span< T > data) const
Definition: BKE_spline.hh:228
Spline(const CurveType type)
Definition: BKE_spline.hh:79
blender::Span< blender::float3 > evaluated_normals() const
Definition: spline_base.cc:361
blender::bke::CustomDataAttributes attributes
Definition: BKE_spline.hh:56
void sample_with_index_factors(const blender::GVArray &src, blender::Span< float > index_factors, blender::GMutableSpan dst) const
Definition: spline_base.cc:503
static void copy_base_settings(const Spline &src, Spline &dst)
Definition: spline_base.cc:30
virtual blender::MutableSpan< float > radii()=0
void sample_with_index_factors(blender::Span< T > src, blender::Span< float > index_factors, blender::MutableSpan< T > dst) const
Definition: BKE_spline.hh:214
virtual void mark_cache_invalid()=0
void reverse()
Definition: spline_base.cc:94
bool is_cyclic() const
Definition: spline_base.cc:143
virtual blender::GVArray interpolate_to_evaluated(const blender::GVArray &src) const =0
virtual ~Spline()=default
bool normal_cache_dirty_
Definition: BKE_spline.hh:70
virtual void copy_settings(Spline &dst) const =0
virtual blender::Span< blender::float3 > evaluated_positions() const =0
Spline(Spline &other)
Definition: BKE_spline.hh:82
LookupResult lookup_evaluated_length(float length) const
Definition: spline_base.cc:405
blender::Span< blender::float3 > evaluated_tangents() const
Definition: spline_base.cc:234
bool length_cache_dirty_
Definition: BKE_spline.hh:75
int segments_num() const
Definition: spline_base.cc:136
SplinePtr copy_only_settings() const
Definition: spline_base.cc:60
virtual void correct_end_tangents() const =0
virtual blender::Span< blender::float3 > positions() const =0
virtual void copy_data(Spline &dst) const =0
VArray< T > typed() const
Curve curve
SyclQueue void void * src
ListBase splines
Definition: mask.c:265
ccl_device_inline float4 mask(const int4 &mask, const float4 &a)
Definition: math_float4.h:513
#define T
bool check_valid_num_and_order(int points_num, int8_t order, bool cyclic, KnotsMode knots_mode)
Definition: curve_nurbs.cc:13
void calculate_knots(int points_num, KnotsMode mode, int8_t order, bool cyclic, MutableSpan< float > knots)
Definition: curve_nurbs.cc:52
void calculate_basis_cache(int points_num, int evaluated_num, int8_t order, bool cyclic, Span< float > knots, BasisCache &basis_cache)
Definition: curve_nurbs.cc:149
int knots_num(int points_num, int8_t order, bool cyclic)
Definition: curve_nurbs.cc:44
#define min(a, b)
Definition: sort.c:35
unsigned char uint8_t
Definition: stdint.h:78
signed char int8_t
Definition: stdint.h:75
blender::float3 right_handle
Definition: BKE_spline.hh:398
blender::float3 position
Definition: BKE_spline.hh:397
blender::float3 left_handle
Definition: BKE_spline.hh:396
blender::float3 handle_prev
Definition: BKE_spline.hh:395
blender::float3 handle_next
Definition: BKE_spline.hh:399
CurveEval()=default
blender::Span< SplinePtr > splines() const
Definition: curve_eval.cc:36
blender::bke::CustomDataAttributes attributes
Definition: BKE_spline.hh:617
CurveEval(const CurveEval &other)
Definition: BKE_spline.hh:620
blender::Vector< int > start_indices
Definition: BKE_spline.hh:457
blender::Vector< float > weights
Definition: BKE_spline.hh:453
float max
bool override
Definition: wm_files.c:1022