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/intern/curve_eval.cc')
-rw-r--r--source/blender/blenkernel/intern/curve_eval.cc52
1 files changed, 49 insertions, 3 deletions
diff --git a/source/blender/blenkernel/intern/curve_eval.cc b/source/blender/blenkernel/intern/curve_eval.cc
index 1679f21516a..9cafe1124b1 100644
--- a/source/blender/blenkernel/intern/curve_eval.cc
+++ b/source/blender/blenkernel/intern/curve_eval.cc
@@ -16,7 +16,9 @@
#include "BLI_array.hh"
#include "BLI_listbase.h"
+#include "BLI_map.hh"
#include "BLI_span.hh"
+#include "BLI_string_ref.hh"
#include "DNA_curve_types.h"
@@ -26,7 +28,9 @@
using blender::Array;
using blender::float3;
using blender::float4x4;
+using blender::Map;
using blender::Span;
+using blender::StringRefNull;
blender::Span<SplinePtr> CurveEval::splines() const
{
@@ -38,6 +42,9 @@ blender::MutableSpan<SplinePtr> CurveEval::splines()
return splines_;
}
+/**
+ * \warning Call #reallocate on the spline's attributes after adding all splines.
+ */
void CurveEval::add_spline(SplinePtr spline)
{
splines_.append(std::move(spline));
@@ -178,7 +185,7 @@ std::unique_ptr<CurveEval> curve_eval_from_dna_curve(const Curve &dna_curve)
bezt.radius,
bezt.tilt);
}
-
+ spline->attributes.reallocate(spline->size());
curve->add_spline(std::move(spline));
break;
}
@@ -192,7 +199,7 @@ std::unique_ptr<CurveEval> curve_eval_from_dna_curve(const Curve &dna_curve)
for (const BPoint &bp : Span(nurb->bp, nurb->pntsu)) {
spline->add_point(bp.vec, bp.radius, bp.tilt, bp.vec[3]);
}
-
+ spline->attributes.reallocate(spline->size());
curve->add_spline(std::move(spline));
break;
}
@@ -203,7 +210,7 @@ std::unique_ptr<CurveEval> curve_eval_from_dna_curve(const Curve &dna_curve)
for (const BPoint &bp : Span(nurb->bp, nurb->pntsu)) {
spline->add_point(bp.vec, bp.radius, bp.tilt);
}
-
+ spline->attributes.reallocate(spline->size());
curve->add_spline(std::move(spline));
break;
}
@@ -214,6 +221,9 @@ std::unique_ptr<CurveEval> curve_eval_from_dna_curve(const Curve &dna_curve)
}
}
+ /* Though the curve has no attributes, this is necessary to properly set the custom data size. */
+ curve->attributes.reallocate(curve->splines().size());
+
/* Note: Normal mode is stored separately in each spline to facilitate combining splines
* from multiple curve objects, where the value may be different. */
const Spline::NormalCalculationMode normal_mode = normal_mode_from_dna_curve(
@@ -224,3 +234,39 @@ std::unique_ptr<CurveEval> curve_eval_from_dna_curve(const Curve &dna_curve)
return curve;
}
+
+/**
+ * Check the invariants that curve control point attributes should always uphold, necessary
+ * because attributes are stored on splines rather than in a flat array on the curve:
+ * - The same set of attributes exists on every spline.
+ * - Attributes with the same name have the same type on every spline.
+ */
+void CurveEval::assert_valid_point_attributes() const
+{
+#ifdef DEBUG
+ if (splines_.size() == 0) {
+ return;
+ }
+ const int layer_len = splines_.first()->attributes.data.totlayer;
+ Map<StringRefNull, AttributeMetaData> map;
+ for (const SplinePtr &spline : splines_) {
+ BLI_assert(spline->attributes.data.totlayer == layer_len);
+ spline->attributes.foreach_attribute(
+ [&](StringRefNull name, const AttributeMetaData &meta_data) {
+ map.add_or_modify(
+ name,
+ [&](AttributeMetaData *map_data) {
+ /* All unique attribute names should be added on the first spline. */
+ BLI_assert(spline == splines_.first());
+ *map_data = meta_data;
+ },
+ [&](AttributeMetaData *map_data) {
+ /* Attributes on different splines should all have the same type. */
+ BLI_assert(meta_data == *map_data);
+ });
+ return true;
+ },
+ ATTR_DOMAIN_POINT);
+ }
+#endif
+} \ No newline at end of file