[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