Blender  V3.3
curve_eval.cc
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-or-later */
2 
3 #include "BLI_array.hh"
4 #include "BLI_index_range.hh"
5 #include "BLI_listbase.h"
6 #include "BLI_map.hh"
7 #include "BLI_span.hh"
8 #include "BLI_string_ref.hh"
9 #include "BLI_task.hh"
10 #include "BLI_vector.hh"
11 
12 #include "DNA_curve_types.h"
13 
15 #include "BKE_curve.h"
16 #include "BKE_curves.hh"
17 #include "BKE_geometry_set.hh"
18 #include "BKE_spline.hh"
19 
20 using blender::Array;
21 using blender::float3;
22 using blender::float4x4;
23 using blender::GVArray;
26 using blender::Map;
28 using blender::Span;
30 using blender::VArray;
32 using blender::Vector;
35 
37 {
38  return splines_;
39 }
40 
42 {
43  return splines_;
44 }
45 
47 {
48  for (const SplinePtr &spline : this->splines()) {
49  if (spline->type() == type) {
50  return true;
51  }
52  }
53  return false;
54 }
55 
56 void CurveEval::resize(const int size)
57 {
58  splines_.resize(size);
60 }
61 
63 {
64  splines_.append(std::move(spline));
65 }
66 
68 {
69  for (SplinePtr &spline : splines) {
70  this->add_spline(std::move(spline));
71  }
72 }
73 
75 {
76  for (int i = mask.size() - 1; i >= 0; i--) {
77  splines_.remove_and_reorder(mask.indices()[i]);
78  }
79 }
80 
81 void CurveEval::translate(const float3 &translation)
82 {
83  for (SplinePtr &spline : this->splines()) {
84  spline->translate(translation);
85  spline->mark_cache_invalid();
86  }
87 }
88 
89 void CurveEval::transform(const float4x4 &matrix)
90 {
91  for (SplinePtr &spline : this->splines()) {
92  spline->transform(matrix);
93  }
94 }
95 
96 bool CurveEval::bounds_min_max(float3 &min, float3 &max, const bool use_evaluated) const
97 {
98  bool have_minmax = false;
99  for (const SplinePtr &spline : this->splines()) {
100  if (spline->size()) {
101  spline->bounds_min_max(min, max, use_evaluated);
102  have_minmax = true;
103  }
104  }
105 
106  return have_minmax;
107 }
108 
110 {
111  float length = 0.0f;
112  for (const SplinePtr &spline : this->splines()) {
113  length += spline->length();
114  }
115  return length;
116 }
117 
119 {
120  int count = 0;
121  for (const SplinePtr &spline : this->splines()) {
122  count += spline->size();
123  }
124  return count;
125 }
126 
128 {
129  Array<int> offsets(splines_.size() + 1);
130  int offset = 0;
131  for (const int i : splines_.index_range()) {
132  offsets[i] = offset;
133  offset += splines_[i]->size();
134  }
135  offsets.last() = offset;
136  return offsets;
137 }
138 
140 {
141  Array<int> offsets(splines_.size() + 1);
142  int offset = 0;
143  for (const int i : splines_.index_range()) {
144  offsets[i] = offset;
145  offset += splines_[i]->evaluated_points_num();
146  }
147  offsets.last() = offset;
148  return offsets;
149 }
150 
152 {
153  Array<float> spline_lengths(splines_.size() + 1);
154  float spline_length = 0.0f;
155  for (const int i : splines_.index_range()) {
156  spline_lengths[i] = spline_length;
157  spline_length += splines_[i]->length();
158  }
159  spline_lengths.last() = spline_length;
160  return spline_lengths;
161 }
162 
164 {
165  for (SplinePtr &spline : splines_) {
166  spline->mark_cache_invalid();
167  }
168 }
169 
171 {
172  switch (dna_handle_type) {
173  case HD_FREE:
174  return BEZIER_HANDLE_FREE;
175  case HD_AUTO:
176  return BEZIER_HANDLE_AUTO;
177  case HD_VECT:
178  return BEZIER_HANDLE_VECTOR;
179  case HD_ALIGN:
180  return BEZIER_HANDLE_ALIGN;
181  case HD_AUTO_ANIM:
182  return BEZIER_HANDLE_AUTO;
183  case HD_ALIGN_DOUBLESIDE:
184  return BEZIER_HANDLE_ALIGN;
185  }
187  return BEZIER_HANDLE_AUTO;
188 }
189 
190 static NormalMode normal_mode_from_dna_curve(const int twist_mode)
191 {
192  switch (twist_mode) {
193  case CU_TWIST_Z_UP:
194  case CU_TWIST_TANGENT:
195  return NORMAL_MODE_Z_UP;
196  case CU_TWIST_MINIMUM:
198  }
201 }
202 
203 static KnotsMode knots_mode_from_dna_nurb(const short flag)
204 {
205  switch (flag & (CU_NURB_ENDPOINT | CU_NURB_BEZIER)) {
206  case CU_NURB_ENDPOINT:
208  case CU_NURB_BEZIER:
209  return NURBS_KNOT_MODE_BEZIER;
212  default:
213  return NURBS_KNOT_MODE_NORMAL;
214  }
215 
217  return NURBS_KNOT_MODE_NORMAL;
218 }
219 
221 {
222  std::unique_ptr<BezierSpline> spline = std::make_unique<BezierSpline>();
223  spline->set_resolution(nurb.resolu);
224  spline->set_cyclic(nurb.flagu & CU_NURB_CYCLIC);
225 
226  Span<const BezTriple> src_points{nurb.bezt, nurb.pntsu};
227  spline->resize(src_points.size());
228  MutableSpan<float3> positions = spline->positions();
229  MutableSpan<float3> handle_positions_left = spline->handle_positions_left(true);
230  MutableSpan<float3> handle_positions_right = spline->handle_positions_right(true);
231  MutableSpan<int8_t> handle_types_left = spline->handle_types_left();
232  MutableSpan<int8_t> handle_types_right = spline->handle_types_right();
233  MutableSpan<float> radii = spline->radii();
234  MutableSpan<float> tilts = spline->tilts();
235 
236  blender::threading::parallel_for(src_points.index_range(), 2048, [&](IndexRange range) {
237  for (const int i : range) {
238  const BezTriple &bezt = src_points[i];
239  positions[i] = bezt.vec[1];
240  handle_positions_left[i] = bezt.vec[0];
241  handle_types_left[i] = handle_type_from_dna_bezt((eBezTriple_Handle)bezt.h1);
242  handle_positions_right[i] = bezt.vec[2];
243  handle_types_right[i] = handle_type_from_dna_bezt((eBezTriple_Handle)bezt.h2);
244  radii[i] = bezt.radius;
245  tilts[i] = bezt.tilt;
246  }
247  });
248 
249  return spline;
250 }
251 
253 {
254  std::unique_ptr<NURBSpline> spline = std::make_unique<NURBSpline>();
255  spline->set_resolution(nurb.resolu);
256  spline->set_cyclic(nurb.flagu & CU_NURB_CYCLIC);
257  spline->set_order(nurb.orderu);
258  spline->knots_mode = knots_mode_from_dna_nurb(nurb.flagu);
259 
260  Span<const BPoint> src_points{nurb.bp, nurb.pntsu};
261  spline->resize(src_points.size());
262  MutableSpan<float3> positions = spline->positions();
263  MutableSpan<float> weights = spline->weights();
264  MutableSpan<float> radii = spline->radii();
265  MutableSpan<float> tilts = spline->tilts();
266 
267  blender::threading::parallel_for(src_points.index_range(), 2048, [&](IndexRange range) {
268  for (const int i : range) {
269  const BPoint &bp = src_points[i];
270  positions[i] = bp.vec;
271  weights[i] = bp.vec[3];
272  radii[i] = bp.radius;
273  tilts[i] = bp.tilt;
274  }
275  });
276 
277  return spline;
278 }
279 
281 {
282  std::unique_ptr<PolySpline> spline = std::make_unique<PolySpline>();
283  spline->set_cyclic(nurb.flagu & CU_NURB_CYCLIC);
284 
285  Span<const BPoint> src_points{nurb.bp, nurb.pntsu};
286  spline->resize(src_points.size());
287  MutableSpan<float3> positions = spline->positions();
288  MutableSpan<float> radii = spline->radii();
289  MutableSpan<float> tilts = spline->tilts();
290 
291  blender::threading::parallel_for(src_points.index_range(), 2048, [&](IndexRange range) {
292  for (const int i : range) {
293  const BPoint &bp = src_points[i];
294  positions[i] = bp.vec;
295  radii[i] = bp.radius;
296  tilts[i] = bp.tilt;
297  }
298  });
299 
300  return spline;
301 }
302 
303 std::unique_ptr<CurveEval> curve_eval_from_dna_curve(const Curve &dna_curve,
304  const ListBase &nurbs_list)
305 {
306  Vector<const Nurb *> nurbs(nurbs_list);
307 
308  std::unique_ptr<CurveEval> curve = std::make_unique<CurveEval>();
309  curve->resize(nurbs.size());
310  MutableSpan<SplinePtr> splines = curve->splines();
311 
312  blender::threading::parallel_for(nurbs.index_range(), 256, [&](IndexRange range) {
313  for (const int i : range) {
314  switch (nurbs[i]->type) {
315  case CU_BEZIER:
316  splines[i] = spline_from_dna_bezier(*nurbs[i]);
317  break;
318  case CU_NURBS:
319  splines[i] = spline_from_dna_nurbs(*nurbs[i]);
320  break;
321  case CU_POLY:
322  splines[i] = spline_from_dna_poly(*nurbs[i]);
323  break;
324  default:
325  BLI_assert_unreachable();
326  break;
327  }
328  }
329  });
330 
331  /* Normal mode is stored separately in each spline to facilitate combining
332  * splines from multiple curve objects, where the value may be different. */
333  const NormalMode normal_mode = normal_mode_from_dna_curve(dna_curve.twist_mode);
334  for (SplinePtr &spline : curve->splines()) {
335  spline->normal_mode = normal_mode;
336  }
337 
338  return curve;
339 }
340 
341 std::unique_ptr<CurveEval> curve_eval_from_dna_curve(const Curve &dna_curve)
342 {
343  return curve_eval_from_dna_curve(dna_curve, *BKE_curve_nurbs_get_for_read(&dna_curve));
344 }
345 
347  const blender::bke::AttributeAccessor &src_attributes,
349  Span<std::string> skip)
350 {
351  src_attributes.for_all([&](const AttributeIDRef &id, const AttributeMetaData meta_data) {
352  if (id.is_named() && skip.contains(id.name())) {
353  return true;
354  }
355 
356  GVArray src_attribute = src_attributes.lookup(id, meta_data.domain, meta_data.data_type);
357  if (!src_attribute) {
358  return true;
359  }
360  GVArraySpan src_attribute_data{src_attribute};
361 
362  blender::bke::GAttributeWriter dst_attribute = dst_attributes.lookup_or_add_for_write(
363  id, meta_data.domain, meta_data.data_type);
364  if (!dst_attribute) {
365  return true;
366  }
367  dst_attribute.varray.set_all(src_attribute_data.data());
368  dst_attribute.finish();
369  return true;
370  });
371 }
372 
373 std::unique_ptr<CurveEval> curves_to_curve_eval(const Curves &curves_id)
374 {
375  CurveComponent src_component;
376  src_component.replace(&const_cast<Curves &>(curves_id), GeometryOwnershipType::ReadOnly);
378  curves_id.geometry);
379  const blender::bke::AttributeAccessor src_attributes = curves.attributes();
380 
381  VArray<int> resolution = curves.resolution();
382  VArray<int8_t> normal_mode = curves.normal_mode();
383 
384  VArraySpan<float> nurbs_weights{
385  src_attributes.lookup_or_default<float>("nurbs_weight", ATTR_DOMAIN_POINT, 1.0f)};
386  VArraySpan<int8_t> nurbs_orders{
387  src_attributes.lookup_or_default<int8_t>("nurbs_order", ATTR_DOMAIN_CURVE, 4)};
388  VArraySpan<int8_t> nurbs_knots_modes{
389  src_attributes.lookup_or_default<int8_t>("knots_mode", ATTR_DOMAIN_CURVE, 0)};
390 
391  VArraySpan<int8_t> handle_types_right{
392  src_attributes.lookup_or_default<int8_t>("handle_type_right", ATTR_DOMAIN_POINT, 0)};
393  VArraySpan<int8_t> handle_types_left{
394  src_attributes.lookup_or_default<int8_t>("handle_type_left", ATTR_DOMAIN_POINT, 0)};
395 
396  /* Create splines with the correct size and type. */
397  VArray<int8_t> curve_types = curves.curve_types();
398  std::unique_ptr<CurveEval> curve_eval = std::make_unique<CurveEval>();
399  for (const int curve_index : curve_types.index_range()) {
400  const IndexRange points = curves.points_for_curve(curve_index);
401 
402  std::unique_ptr<Spline> spline;
403  /* #CurveEval does not support catmull rom curves, so convert those to poly splines. */
404  switch (std::max<int8_t>(1, curve_types[curve_index])) {
405  case CURVE_TYPE_POLY: {
406  spline = std::make_unique<PolySpline>();
407  spline->resize(points.size());
408  break;
409  }
410  case CURVE_TYPE_BEZIER: {
411  std::unique_ptr<BezierSpline> bezier_spline = std::make_unique<BezierSpline>();
412  bezier_spline->resize(points.size());
413  bezier_spline->set_resolution(resolution[curve_index]);
414  bezier_spline->handle_types_left().copy_from(handle_types_left.slice(points));
415  bezier_spline->handle_types_right().copy_from(handle_types_right.slice(points));
416 
417  spline = std::move(bezier_spline);
418  break;
419  }
420  case CURVE_TYPE_NURBS: {
421  std::unique_ptr<NURBSpline> nurb_spline = std::make_unique<NURBSpline>();
422  nurb_spline->resize(points.size());
423  nurb_spline->set_resolution(resolution[curve_index]);
424  nurb_spline->weights().copy_from(nurbs_weights.slice(points));
425  nurb_spline->set_order(nurbs_orders[curve_index]);
426  nurb_spline->knots_mode = static_cast<KnotsMode>(nurbs_knots_modes[curve_index]);
427 
428  spline = std::move(nurb_spline);
429  break;
430  }
432  /* Not supported yet. */
434  continue;
435  }
436  spline->positions().fill(float3(0));
437  spline->tilts().fill(0.0f);
438  spline->radii().fill(1.0f);
439  spline->normal_mode = static_cast<NormalMode>(normal_mode[curve_index]);
440  curve_eval->add_spline(std::move(spline));
441  }
442 
443  curve_eval->attributes.reallocate(curve_eval->splines().size());
444 
445  CurveComponentLegacy dst_component;
446  dst_component.replace(curve_eval.get(), GeometryOwnershipType::Editable);
447  blender::bke::MutableAttributeAccessor dst_attributes = *dst_component.attributes_for_write();
448 
449  copy_attributes_between_components(src_attributes,
450  dst_attributes,
451  {"curve_type",
452  "resolution",
453  "normal_mode",
454  "nurbs_weight",
455  "nurbs_order",
456  "knots_mode",
457  "handle_type_right",
458  "handle_type_left"});
459 
460  return curve_eval;
461 }
462 
464 {
466  curve_eval.splines().size());
467  CurveComponent dst_component;
468  dst_component.replace(curves_id, GeometryOwnershipType::Editable);
469  blender::bke::MutableAttributeAccessor dst_attributes = *dst_component.attributes_for_write();
470 
472  curves.offsets_for_write().copy_from(curve_eval.control_point_offsets());
473  MutableSpan<int8_t> curve_types = curves.curve_types_for_write();
474 
476  dst_attributes.lookup_or_add_for_write_only_span<int8_t>("normal_mode", ATTR_DOMAIN_CURVE);
480  if (curve_eval.has_spline_with_type(CURVE_TYPE_NURBS)) {
481  nurbs_weight = dst_attributes.lookup_or_add_for_write_only_span<float>("nurbs_weight",
483  nurbs_order = dst_attributes.lookup_or_add_for_write_only_span<int8_t>("nurbs_order",
485  nurbs_knots_mode = dst_attributes.lookup_or_add_for_write_only_span<int8_t>("knots_mode",
487  }
490  if (curve_eval.has_spline_with_type(CURVE_TYPE_BEZIER)) {
491  handle_type_right = dst_attributes.lookup_or_add_for_write_only_span<int8_t>(
492  "handle_type_right", ATTR_DOMAIN_POINT);
493  handle_type_left = dst_attributes.lookup_or_add_for_write_only_span<int8_t>("handle_type_left",
495  }
496 
497  for (const int curve_index : curve_eval.splines().index_range()) {
498  const Spline &spline = *curve_eval.splines()[curve_index];
499  curve_types[curve_index] = curve_eval.splines()[curve_index]->type();
500  normal_mode.span[curve_index] = curve_eval.splines()[curve_index]->normal_mode;
501  const IndexRange points = curves.points_for_curve(curve_index);
502 
503  switch (spline.type()) {
504  case CURVE_TYPE_POLY:
505  break;
506  case CURVE_TYPE_BEZIER: {
507  const BezierSpline &src = static_cast<const BezierSpline &>(spline);
508  handle_type_right.span.slice(points).copy_from(src.handle_types_right());
509  handle_type_left.span.slice(points).copy_from(src.handle_types_left());
510  break;
511  }
512  case CURVE_TYPE_NURBS: {
513  const NURBSpline &src = static_cast<const NURBSpline &>(spline);
514  nurbs_knots_mode.span[curve_index] = static_cast<int8_t>(src.knots_mode);
515  nurbs_order.span[curve_index] = src.order();
516  nurbs_weight.span.slice(points).copy_from(src.weights());
517  break;
518  }
519  case CURVE_TYPE_CATMULL_ROM: {
521  break;
522  }
523  }
524  }
525 
526  curves.update_curve_types();
527 
528  normal_mode.finish();
529  nurbs_weight.finish();
530  nurbs_order.finish();
531  nurbs_knots_mode.finish();
532  handle_type_right.finish();
533  handle_type_left.finish();
534 
535  CurveComponentLegacy src_component;
536  src_component.replace(&const_cast<CurveEval &>(curve_eval), GeometryOwnershipType::ReadOnly);
537  const blender::bke::AttributeAccessor src_attributes = *src_component.attributes();
538 
539  copy_attributes_between_components(src_attributes, dst_attributes, {});
540 
541  return curves_id;
542 }
543 
545 {
546 #ifdef DEBUG
547  if (splines_.size() == 0) {
548  return;
549  }
550  const int layer_len = splines_.first()->attributes.data.totlayer;
551 
552  Array<AttributeIDRef> ids_in_order(layer_len);
553  Array<AttributeMetaData> meta_data_in_order(layer_len);
554 
555  {
556  int i = 0;
557  splines_.first()->attributes.foreach_attribute(
558  [&](const AttributeIDRef &attribute_id, const AttributeMetaData &meta_data) {
559  ids_in_order[i] = attribute_id;
560  meta_data_in_order[i] = meta_data;
561  i++;
562  return true;
563  },
565  }
566 
567  for (const SplinePtr &spline : splines_) {
568  /* All splines should have the same number of attributes. */
569  BLI_assert(spline->attributes.data.totlayer == layer_len);
570 
571  int i = 0;
572  spline->attributes.foreach_attribute(
573  [&](const AttributeIDRef &attribute_id, const AttributeMetaData &meta_data) {
574  /* Attribute names and IDs should have the same order and exist on all splines. */
575  BLI_assert(attribute_id == ids_in_order[i]);
576 
577  /* Attributes with the same ID different splines should all have the same type. */
578  BLI_assert(meta_data == meta_data_in_order[i]);
579 
580  i++;
581  return true;
582  },
584  }
585 
586 #endif
587 }
@ ATTR_DOMAIN_CURVE
Definition: BKE_attribute.h:31
@ ATTR_DOMAIN_POINT
Definition: BKE_attribute.h:27
const ListBase * BKE_curve_nurbs_get_for_read(const struct Curve *cu)
Low-level operations for curves.
std::unique_ptr< Spline > SplinePtr
Definition: BKE_spline.hh:26
#define BLI_assert_unreachable()
Definition: BLI_assert.h:93
#define BLI_assert(a)
Definition: BLI_assert.h:46
@ CU_NURB_CYCLIC
@ CU_NURB_ENDPOINT
@ CU_NURB_BEZIER
eBezTriple_Handle
@ HD_AUTO_ANIM
@ HD_VECT
@ HD_FREE
@ HD_AUTO
@ HD_ALIGN_DOUBLESIDE
@ HD_ALIGN
@ CU_TWIST_MINIMUM
@ CU_TWIST_TANGENT
@ CU_TWIST_Z_UP
CurveType
@ CURVE_TYPE_BEZIER
@ CURVE_TYPE_NURBS
@ CURVE_TYPE_POLY
@ CURVE_TYPE_CATMULL_ROM
NormalMode
@ NORMAL_MODE_MINIMUM_TWIST
@ NORMAL_MODE_Z_UP
HandleType
@ BEZIER_HANDLE_FREE
@ BEZIER_HANDLE_ALIGN
@ BEZIER_HANDLE_VECTOR
@ BEZIER_HANDLE_AUTO
KnotsMode
@ NURBS_KNOT_MODE_ENDPOINT
@ NURBS_KNOT_MODE_NORMAL
@ NURBS_KNOT_MODE_BEZIER
@ NURBS_KNOT_MODE_ENDPOINT_BEZIER
_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 type
float float4x4[4][4]
float float3[3]
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
in reality light always falls off quadratically Particle Retrieve the data of the particle that spawned the object for example to give variation to multiple instances of an object Point Retrieve information about points in a point cloud Retrieve the edges of an object as it appears to Cycles topology will always appear triangulated Convert a blackbody temperature to an RGB value Normal Map
static DBVT_INLINE btScalar size(const btDbvtVolume &a)
Definition: btDbvt.cpp:52
void replace(CurveEval *curve, GeometryOwnershipType ownership=GeometryOwnershipType::Owned)
std::optional< blender::bke::AttributeAccessor > attributes() const final
std::optional< blender::bke::MutableAttributeAccessor > attributes_for_write() final
void replace(Curves *curve, GeometryOwnershipType ownership=GeometryOwnershipType::Owned)
std::optional< blender::bke::MutableAttributeAccessor > attributes_for_write() final
CurveType type() const
Definition: spline_base.cc:25
const T & last(const int64_t n=0) const
Definition: BLI_array.hh:284
void set_all(const void *src)
constexpr int64_t size() const
constexpr bool contains(const T &value) const
Definition: BLI_span.hh:265
IndexRange index_range() const
int64_t size() const
Definition: BLI_vector.hh:694
void remove_and_reorder(const int64_t index)
Definition: BLI_vector.hh:743
void append(const T &value)
Definition: BLI_vector.hh:433
IndexRange index_range() const
Definition: BLI_vector.hh:920
void resize(const int64_t new_size)
Definition: BLI_vector.hh:353
const T & first() const
Definition: BLI_vector.hh:680
GAttributeReader lookup(const AttributeIDRef &attribute_id) const
GVArray lookup_or_default(const AttributeIDRef &attribute_id, const eAttrDomain domain, const eCustomDataType data_type, const void *default_value=nullptr) const
bool for_all(const AttributeForeachCallback fn) const
static CurvesGeometry & wrap(::CurvesGeometry &dna_struct)
Definition: BKE_curves.hh:138
GSpanAttributeWriter lookup_or_add_for_write_only_span(const AttributeIDRef &attribute_id, const eAttrDomain domain, const eCustomDataType data_type)
GAttributeWriter lookup_or_add_for_write(const AttributeIDRef &attribute_id, const eAttrDomain domain, const eCustomDataType data_type, const AttributeInit &initializer=AttributeInitDefault())
static SplinePtr spline_from_dna_nurbs(const Nurb &nurb)
Definition: curve_eval.cc:252
std::unique_ptr< CurveEval > curve_eval_from_dna_curve(const Curve &dna_curve, const ListBase &nurbs_list)
Definition: curve_eval.cc:303
std::unique_ptr< CurveEval > curves_to_curve_eval(const Curves &curves_id)
Definition: curve_eval.cc:373
static SplinePtr spline_from_dna_poly(const Nurb &nurb)
Definition: curve_eval.cc:280
static KnotsMode knots_mode_from_dna_nurb(const short flag)
Definition: curve_eval.cc:203
static SplinePtr spline_from_dna_bezier(const Nurb &nurb)
Definition: curve_eval.cc:220
static HandleType handle_type_from_dna_bezt(const eBezTriple_Handle dna_handle_type)
Definition: curve_eval.cc:170
Curves * curve_eval_to_curves(const CurveEval &curve_eval)
Definition: curve_eval.cc:463
static void copy_attributes_between_components(const blender::bke::AttributeAccessor &src_attributes, blender::bke::MutableAttributeAccessor &dst_attributes, Span< std::string > skip)
Definition: curve_eval.cc:346
static NormalMode normal_mode_from_dna_curve(const int twist_mode)
Definition: curve_eval.cc:190
Curve curve
SyclQueue void void * src
int count
ccl_gpu_kernel_postfix ccl_global float int int int int float bool int offset
ListBase splines
Definition: mask.c:265
ccl_device_inline float4 mask(const int4 &mask, const float4 &a)
Definition: math_float4.h:513
Curves * curves_new_nomain(int points_num, int curves_num)
Definition: curves.cc:367
T length(const vec_base< T, Size > &a)
void parallel_for(IndexRange range, int64_t grain_size, const Function &function)
Definition: BLI_task.hh:51
vec_base< float, 3 > float3
MutableSpan< float3 > positions
MutableSpan< float > radii
#define min(a, b)
Definition: sort.c:35
signed char int8_t
Definition: stdint.h:75
blender::Array< int > control_point_offsets() const
Definition: curve_eval.cc:127
blender::Span< SplinePtr > splines() const
Definition: curve_eval.cc:36
void mark_cache_invalid()
Definition: curve_eval.cc:163
void translate(const blender::float3 &translation)
Definition: curve_eval.cc:81
blender::Array< float > accumulated_spline_lengths() const
Definition: curve_eval.cc:151
blender::bke::CustomDataAttributes attributes
Definition: BKE_spline.hh:617
blender::Array< int > evaluated_point_offsets() const
Definition: curve_eval.cc:139
void resize(int size)
Definition: curve_eval.cc:56
int total_control_point_num() const
Definition: curve_eval.cc:118
void assert_valid_point_attributes() const
Definition: curve_eval.cc:544
float total_length() const
Definition: curve_eval.cc:109
bool bounds_min_max(blender::float3 &min, blender::float3 &max, bool use_evaluated) const
Definition: curve_eval.cc:96
void add_spline(SplinePtr spline)
Definition: curve_eval.cc:62
void add_splines(blender::MutableSpan< SplinePtr > splines)
Definition: curve_eval.cc:67
void transform(const blender::float4x4 &matrix)
Definition: curve_eval.cc:89
bool has_spline_with_type(const CurveType type) const
Definition: curve_eval.cc:46
void remove_splines(blender::IndexMask mask)
Definition: curve_eval.cc:74
CurvesGeometry geometry
short flagu
short orderu
BezTriple * bezt
BPoint * bp
short resolu
float max