[Bf-blender-cvs] [140828037b7] geometry-nodes-curve-support: Geometry Nodes Curves: Initial support for spline attributes
Hans Goudey
noreply at git.blender.org
Sun Apr 4 16:30:43 CEST 2021
Commit: 140828037b7287a9e8c004b1993964ebb4535be0
Author: Hans Goudey
Date: Sat Apr 3 09:39:56 2021 -0500
Branches: geometry-nodes-curve-support
https://developer.blender.org/rB140828037b7287a9e8c004b1993964ebb4535be0
Geometry Nodes Curves: Initial support for spline attributes
Also: Move the evaluation cache to each spline, store spline pointers
instead of a separate list per spline type in `DCurve`, and also curve
to mesh node doesn't work now.
===================================================================
M source/blender/blenkernel/BKE_derived_curve.hh
M source/blender/blenkernel/intern/derived_curve.cc
M source/blender/blenkernel/intern/geometry_component_curve.cc
M source/blender/nodes/geometry/nodes/node_geo_curve_to_mesh.cc
M source/blender/nodes/geometry/nodes/node_geo_transform.cc
===================================================================
diff --git a/source/blender/blenkernel/BKE_derived_curve.hh b/source/blender/blenkernel/BKE_derived_curve.hh
index bde24d0127a..40a87af7101 100644
--- a/source/blender/blenkernel/BKE_derived_curve.hh
+++ b/source/blender/blenkernel/BKE_derived_curve.hh
@@ -56,68 +56,117 @@ struct ControlPointNURBS : ControlPoint {
float weight;
};
-enum class SplineType {
- Bezier,
- Poly,
- NURBS,
-};
-
-struct Spline {
- SplineType type;
+class Spline {
+ public:
+ enum Type {
+ Bezier,
+ NURBS,
+ Poly,
+ };
+ Type type;
virtual int size() const = 0;
+ virtual int resolution() const = 0;
+ virtual void set_resolution(const int value) = 0;
+ virtual void mark_cache_invalid() = 0;
+
+ virtual int evaluated_points_size() const = 0;
+ virtual void ensure_evaluation_cache() const = 0;
+ virtual blender::Span<blender::float3> evaluated_positions() const = 0;
};
-struct SplineBezier : Spline {
+class BezierSpline : public Spline {
+ public:
+ /* TODO: Figure out if I want to store this as a few separate vectors directly in the spline. */
blender::Vector<ControlPointBezier> control_points;
+ int resolution_u;
- blender::Vector<blender::float3> handle_positions_a;
- blender::Vector<blender::float3> positions;
- blender::Vector<blender::float3> handle_positions_b;
+ static constexpr inline Type static_type = Spline::Type::Bezier;
- blender::Vector<BezierHandleType> handle_type_a;
- blender::Vector<BezierHandleType> handle_type_b;
+ private:
+ bool cache_dirty;
int32_t flag; /* Cyclic, smooth. */
- int32_t resolution_u;
- int32_t resolution_v;
+ std::mutex cache_mutex;
+ blender::Vector<blender::float3> evaluated_spline_cache;
+
+ public:
int size() const final
{
return control_points.size();
}
- ~SplineBezier() = default;
+ int resolution() const final
+ {
+ return resolution_u;
+ }
+ void set_resolution(const int value) final
+ {
+ resolution_u = value;
+ }
+
+ void mark_cache_invalid() final
+ {
+ cache_dirty = true;
+ }
+
+ int evaluated_points_size() const final;
+ void ensure_evaluation_cache() const final;
+
+ blender::Span<blender::float3> evaluated_positions() const final
+ {
+ this->ensure_evaluation_cache();
+ return evaluated_spline_cache;
+ }
+
+ ~BezierSpline() = default;
};
-struct SplineNURBS : Spline {
+class SplineNURBS : public Spline {
+ public:
blender::Vector<ControlPointNURBS> control_points;
int32_t flag; /* Cyclic, smooth. */
- int32_t resolution_u;
- int32_t resolution_v;
+ int resolution_u;
uint8_t order;
int size() const final
{
return control_points.size();
}
+
+ int resolution() const final
+ {
+ return resolution_u;
+ }
+ void set_resolution(const int value) final
+ {
+ resolution_u = value;
+ }
+
+ int evaluated_points_size() const final
+ {
+ return 0;
+ }
+ void ensure_evaluation_cache() const final
+ {
+ }
+
+ blender::Span<blender::float3> evaluated_positions() const final
+ {
+ return {};
+ }
};
/* Proposed name to be different from DNA type. */
struct DCurve {
- blender::Vector<SplineBezier> splines_bezier;
+ blender::Vector<Spline *> splines;
int32_t flag; /* 2D. */
/* Attributes. */
// AttributeStorage attributes;
// CustomData *control_point_data;
// CustomData *spline_data;
-
- /* Then maybe whatever caches are necessary, etc. */
- std::mutex cache_mutex;
- blender::Vector<blender::float3> evaluated_spline_cache;
-
- void ensure_evaluation_cache() const;
};
DCurve *dcurve_from_dna_curve(const Curve &curve);
\ No newline at end of file
diff --git a/source/blender/blenkernel/intern/derived_curve.cc b/source/blender/blenkernel/intern/derived_curve.cc
index a3edf9ade36..20ff7e54453 100644
--- a/source/blender/blenkernel/intern/derived_curve.cc
+++ b/source/blender/blenkernel/intern/derived_curve.cc
@@ -53,11 +53,11 @@ DCurve *dcurve_from_dna_curve(const Curve &dna_curve)
{
DCurve *curve = new DCurve();
- curve->splines_bezier.reserve(BLI_listbase_count(&dna_curve.nurb));
+ curve->splines.reserve(BLI_listbase_count(&dna_curve.nurb));
LISTBASE_FOREACH (const Nurb *, nurb, &dna_curve.nurb) {
if (nurb->type == CU_BEZIER) {
- SplineBezier spline;
+ BezierSpline *spline = new BezierSpline();
for (const BezTriple &bezt : Span(nurb->bezt, nurb->pntsu)) {
ControlPointBezier point;
point.handle_position_a = bezt.vec[0];
@@ -67,14 +67,14 @@ DCurve *dcurve_from_dna_curve(const Curve &dna_curve)
point.tilt = bezt.tilt;
point.handle_type_a = handle_type_from_dna_bezt((eBezTriple_Handle)bezt.h1);
point.handle_type_b = handle_type_from_dna_bezt((eBezTriple_Handle)bezt.h2);
- spline.control_points.append(std::move(point));
+ spline->control_points.append(std::move(point));
}
- spline.resolution_u = nurb->resolu;
- spline.resolution_v = nurb->resolv;
- spline.type = SplineType::Bezier;
+ spline->resolution_u = nurb->resolu;
+ // spline.resolution_v = nurb->resolv;
+ spline->type = Spline::Type::Bezier;
- curve->splines_bezier.append(spline);
+ curve->splines.append(spline);
}
else if (nurb->type == CU_NURBS) {
}
@@ -103,52 +103,57 @@ static void evaluate_bezier_part_3d(const float3 point_0,
}
}
-void DCurve::ensure_evaluation_cache() const
+int BezierSpline::evaluated_points_size() const
{
- DCurve *mutable_self = const_cast<DCurve *>(this);
-
- std::lock_guard<std::mutex>(mutable_self->cache_mutex);
-
- mutable_self->evaluated_spline_cache.clear();
-
int total_len = 1;
- for (const SplineBezier &spline : this->splines_bezier) {
- for (const int i : IndexRange(1, spline.control_points.size() - 1)) {
- const ControlPointBezier &point_prev = spline.control_points[i - 1];
- const ControlPointBezier &point = spline.control_points[i];
- if (point_prev.handle_type_b == BezierHandleType::Vector &&
- point.handle_type_a == BezierHandleType::Vector) {
- total_len += 1;
- }
- else {
- total_len += spline.resolution_u;
- }
+ for (const int i : IndexRange(1, this->control_points.size() - 1)) {
+ const ControlPointBezier &point_prev = this->control_points[i - 1];
+ const ControlPointBezier &point = this->control_points[i];
+ if (point_prev.handle_type_b == BezierHandleType::Vector &&
+ point.handle_type_a == BezierHandleType::Vector) {
+ total_len += 1;
+ }
+ else {
+ total_len += this->resolution_u;
}
}
- mutable_self->evaluated_spline_cache.resize(total_len);
+ return total_len;
+}
+
+void BezierSpline::ensure_evaluation_cache() const
+{
+ if (!this->cache_dirty) {
+ return;
+ }
+
+ BezierSpline *mutable_self = const_cast<BezierSpline *>(this);
+ std::lock_guard<std::mutex> lock(mutable_self->cache_mutex);
+ mutable_self->evaluated_spline_cache.clear();
+
+ mutable_self->evaluated_spline_cache.resize(this->evaluated_points_size());
MutableSpan<float3> positions(mutable_self->evaluated_spline_cache);
int offset = 0;
- for (const SplineBezier &spline : this->splines_bezier) {
- for (const int i : IndexRange(1, spline.control_points.size() - 1)) {
- const ControlPointBezier &point_prev = spline.control_points[i - 1];
- const ControlPointBezier &point = spline.control_points[i];
-
- if (point_prev.handle_type_b == BezierHandleType::Vector &&
- point.handle_type_a == BezierHandleType::Vector) {
- offset++;
- }
- else {
- const int resolution = spline.resolution_u;
- evaluate_bezier_part_3d(point_prev.position,
- point_prev.handle_position_b,
- point.handle_position_a,
- point.position,
- positions.slice(offset, resolution));
- offset += resolution;
- }
+ for (const int i : IndexRange(1, this->control_points.size() - 1)) {
+ const ControlPointBezier &point_prev = this->control_points[i - 1];
+ const ControlPointBezier &point = this->control_points[i];
+
+ if (point_prev.handle_type_b == BezierHandleType::Vector &&
+ point.handle_type_a == BezierHandleType::Vector) {
+ offset++;
+ }
+ else {
+ const int resolution = this->resolution_u;
+ evaluate_bezier_part_3d(point_prev.position,
+ point_prev.handle_position_b,
+ point.handle_position_a,
+ point.position,
+ positions.slice(offset, resolution));
+ offset += resolution;
}
}
+
+ mutable_self->cache_dirty = false;
}
diff --git a/source/blender/blenkernel/intern/geometry_component_curve.cc b/source/blender/blenkernel/intern/geometry_component_curve.cc
index 7254935d3df..9867df3f27b 100644
--- a/source/blender/blenkernel/intern/geometry_component_curve.cc
+++ b/source/blender/blenkernel/intern/geometry_component_curve.cc
@@ -110,24 +110,45 @@ int CurveComponent::attribute_domain_size(const AttributeDomain domain) const
}
if (domain == ATTR_DOMAIN_POINT) {
int total = 0;
- for (const SplineBezier &spline : curve_->splines_bezier) {
- total += spline.size();
+ for (const Spline *spline : curve_->splines) {
+ total += spline->size();
}
return total;
}
if (domain == ATTR_DOMAIN_CURVE) {
- return curve_->splines_bezier.size();
+ return curve_->splines.size();
}
return 0;
}
namespace blender::bke {
-class CurveAttributeProvider final : public BuiltinAttributeProvider {
+class BuiltinSplineAttributeProvider final : public BuiltinAttributeProvider {
+ using AsReadAttribute = ReadAttributePtr (*)(const DCurve &data);
+ using AsWriteAttribute = WriteAttributePtr (*)(DCurve &data);
+ using UpdateOnWrite = void (*)(Spline &spline);
+ const AsReadAttribute as_read_attribute_;
+ const AsWriteAttribute as_write_attribute_;
+ const UpdateOnWrite update_on_write_;
+
public:
- CurveAttributeProvider()
- : BuiltinAttributeProvider(
- "position", ATTR_DOMAIN_POINT, CD_PROP_FLOAT3, NonCreatable, Writable, NonDe
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list