[Bf-blender-cvs] [9ec12c26f16] master: Geometry Nodes: Begin conversion to new curves

Hans Goudey noreply at git.blender.org
Mon Feb 28 16:46:47 CET 2022


Commit: 9ec12c26f16ea3da1e6de95d5d5daf1057464830
Author: Hans Goudey
Date:   Mon Feb 28 10:46:34 2022 -0500
Branches: master
https://developer.blender.org/rB9ec12c26f16ea3da1e6de95d5d5daf1057464830

Geometry Nodes: Begin conversion to new curves

This commit changes `CurveComponent` to store the new curve
type by adding conversions to and from `CurveEval` in most nodes.
This will temporarily make performance of curves in geometry nodes
much worse, but as functionality is implemented for the new type
and it is used in more places, performance will become better than
before.

We still use `CurveEval` for drawing curves, because the new `Curves`
data-block has no evaluated points yet. So the `Curve` ID is still
generated for rendering in the same way as before. It's also still
needed for drawing curve object edit mode overlays.

The old curve component isn't removed yet, because it is still used
to implement the conversions to and from `CurveEval`.

A few more attributes are added to make this possible:
- `nurbs_weight`: The weight for each control point on NURBS curves.
- `nurbs_order`: The order of the NURBS curve
- `knots_mode`: Necessary for conversion, not defined yet.
- `handle_type_{left/right}`: An 8 bit integer attribute.

Differential Revision: https://developer.blender.org/D14145

===================================================================

M	source/blender/blenkernel/BKE_geometry_set.hh
M	source/blender/blenkernel/BKE_spline.hh
M	source/blender/blenkernel/CMakeLists.txt
M	source/blender/blenkernel/intern/curve.cc
M	source/blender/blenkernel/intern/curve_eval.cc
M	source/blender/blenkernel/intern/displist.cc
M	source/blender/blenkernel/intern/geometry_component_curve.cc
A	source/blender/blenkernel/intern/geometry_component_curves.cc
M	source/blender/blenkernel/intern/geometry_set.cc
M	source/blender/blenkernel/intern/mesh_convert.cc
M	source/blender/geometry/intern/realize_instances.cc
M	source/blender/nodes/geometry/nodes/legacy/node_geo_legacy_curve_endpoints.cc
M	source/blender/nodes/geometry/nodes/legacy/node_geo_legacy_curve_reverse.cc
M	source/blender/nodes/geometry/nodes/legacy/node_geo_legacy_curve_select_by_handle_type.cc
M	source/blender/nodes/geometry/nodes/legacy/node_geo_legacy_curve_set_handles.cc
M	source/blender/nodes/geometry/nodes/legacy/node_geo_legacy_curve_spline_type.cc
M	source/blender/nodes/geometry/nodes/legacy/node_geo_legacy_curve_subdivide.cc
M	source/blender/nodes/geometry/nodes/legacy/node_geo_legacy_curve_to_points.cc
M	source/blender/nodes/geometry/nodes/legacy/node_geo_legacy_delete_geometry.cc
M	source/blender/nodes/geometry/nodes/legacy/node_geo_legacy_mesh_to_curve.cc
M	source/blender/nodes/geometry/nodes/node_geo_convex_hull.cc
M	source/blender/nodes/geometry/nodes/node_geo_curve_endpoint_selection.cc
M	source/blender/nodes/geometry/nodes/node_geo_curve_fill.cc
M	source/blender/nodes/geometry/nodes/node_geo_curve_fillet.cc
M	source/blender/nodes/geometry/nodes/node_geo_curve_handle_type_selection.cc
M	source/blender/nodes/geometry/nodes/node_geo_curve_length.cc
M	source/blender/nodes/geometry/nodes/node_geo_curve_primitive_arc.cc
M	source/blender/nodes/geometry/nodes/node_geo_curve_primitive_bezier_segment.cc
M	source/blender/nodes/geometry/nodes/node_geo_curve_primitive_circle.cc
M	source/blender/nodes/geometry/nodes/node_geo_curve_primitive_line.cc
M	source/blender/nodes/geometry/nodes/node_geo_curve_primitive_quadratic_bezier.cc
M	source/blender/nodes/geometry/nodes/node_geo_curve_primitive_quadrilateral.cc
M	source/blender/nodes/geometry/nodes/node_geo_curve_primitive_spiral.cc
M	source/blender/nodes/geometry/nodes/node_geo_curve_primitive_star.cc
M	source/blender/nodes/geometry/nodes/node_geo_curve_resample.cc
M	source/blender/nodes/geometry/nodes/node_geo_curve_reverse.cc
M	source/blender/nodes/geometry/nodes/node_geo_curve_sample.cc
M	source/blender/nodes/geometry/nodes/node_geo_curve_set_handles.cc
M	source/blender/nodes/geometry/nodes/node_geo_curve_spline_parameter.cc
M	source/blender/nodes/geometry/nodes/node_geo_curve_spline_type.cc
M	source/blender/nodes/geometry/nodes/node_geo_curve_subdivide.cc
M	source/blender/nodes/geometry/nodes/node_geo_curve_to_mesh.cc
M	source/blender/nodes/geometry/nodes/node_geo_curve_to_points.cc
M	source/blender/nodes/geometry/nodes/node_geo_curve_trim.cc
M	source/blender/nodes/geometry/nodes/node_geo_delete_geometry.cc
M	source/blender/nodes/geometry/nodes/node_geo_duplicate_elements.cc
M	source/blender/nodes/geometry/nodes/node_geo_input_spline_length.cc
M	source/blender/nodes/geometry/nodes/node_geo_input_tangent.cc
M	source/blender/nodes/geometry/nodes/node_geo_mesh_to_curve.cc
M	source/blender/nodes/geometry/nodes/node_geo_set_curve_handles.cc
M	source/blender/nodes/geometry/nodes/node_geo_set_spline_resolution.cc
M	source/blender/nodes/geometry/nodes/node_geo_string_to_curves.cc
M	source/blender/nodes/geometry/nodes/node_geo_transform.cc

===================================================================

diff --git a/source/blender/blenkernel/BKE_geometry_set.hh b/source/blender/blenkernel/BKE_geometry_set.hh
index d93b3ca95e7..f11bfb7692a 100644
--- a/source/blender/blenkernel/BKE_geometry_set.hh
+++ b/source/blender/blenkernel/BKE_geometry_set.hh
@@ -24,6 +24,7 @@
 
 #include "FN_field.hh"
 
+struct Curves;
 struct Collection;
 struct Curve;
 struct CurveEval;
@@ -415,7 +416,7 @@ struct GeometrySet {
    * Create a new geometry set that only contains the given curve.
    */
   static GeometrySet create_with_curve(
-      CurveEval *curve, GeometryOwnershipType ownership = GeometryOwnershipType::Owned);
+      Curves *curves, GeometryOwnershipType ownership = GeometryOwnershipType::Owned);
 
   /* Utility methods for access. */
   /**
@@ -462,7 +463,7 @@ struct GeometrySet {
   /**
    * Returns a read-only curve or null.
    */
-  const CurveEval *get_curve_for_read() const;
+  const Curves *get_curve_for_read() const;
 
   /**
    * Returns a mutable mesh or null. No ownership is transferred.
@@ -479,7 +480,7 @@ struct GeometrySet {
   /**
    * Returns a mutable curve or null. No ownership is transferred.
    */
-  CurveEval *get_curve_for_write();
+  Curves *get_curve_for_write();
 
   /* Utility methods for replacement. */
   /**
@@ -499,7 +500,7 @@ struct GeometrySet {
   /**
    * Clear the existing curve and replace it with the given one.
    */
-  void replace_curve(CurveEval *curve,
+  void replace_curve(Curves *curves,
                      GeometryOwnershipType ownership = GeometryOwnershipType::Owned);
 
  private:
@@ -632,17 +633,59 @@ class PointCloudComponent : public GeometryComponent {
 };
 
 /**
- * A geometry component that stores curve data, in other words, a group of splines.
- * Curves are stored differently than other geometry components, because the data structure used
- * here does not correspond exactly to the #Curve DNA data structure. A #CurveEval is stored here
- * instead, though the component does give access to a #Curve for interfacing with render engines
- * and other areas of Blender that expect to use a data-block with an #ID.
+ * Legacy runtime-only curves type.
+ * These curves are stored differently than other geometry components, because the data structure
+ * used here does not correspond exactly to the #Curve DNA data structure. A #CurveEval is stored
+ * here instead, though the component does give access to a #Curve for interfacing with render
+ * engines and other areas of Blender that expect to use a data-block with an #ID.
  */
-class CurveComponent : public GeometryComponent {
+class CurveComponentLegacy : public GeometryComponent {
  private:
   CurveEval *curve_ = nullptr;
   GeometryOwnershipType ownership_ = GeometryOwnershipType::Owned;
 
+ public:
+  CurveComponentLegacy();
+  ~CurveComponentLegacy();
+  GeometryComponent *copy() const override;
+
+  void clear();
+  bool has_curve() const;
+  /**
+   * Clear the component and replace it with the new curve.
+   */
+  void replace(CurveEval *curve, GeometryOwnershipType ownership = GeometryOwnershipType::Owned);
+  CurveEval *release();
+
+  const CurveEval *get_for_read() const;
+  CurveEval *get_for_write();
+
+  int attribute_domain_size(AttributeDomain domain) const final;
+
+  bool is_empty() const final;
+
+  bool owns_direct_data() const override;
+  void ensure_owns_direct_data() override;
+
+  static constexpr inline GeometryComponentType static_type = GEO_COMPONENT_TYPE_CURVE;
+
+ private:
+  const blender::bke::ComponentAttributeProviders *get_attribute_providers() const final;
+
+  blender::fn::GVArray attribute_try_adapt_domain_impl(const blender::fn::GVArray &varray,
+                                                       AttributeDomain from_domain,
+                                                       AttributeDomain to_domain) const final;
+};
+
+/**
+ * A geometry component that stores a group of curves, corresponding the the #Curves and
+ * #CurvesGeometry types.
+ */
+class CurveComponent : public GeometryComponent {
+ private:
+  Curves *curves_ = nullptr;
+  GeometryOwnershipType ownership_ = GeometryOwnershipType::Owned;
+
   /**
    * Curve data necessary to hold the draw cache for rendering, consistent over multiple redraws.
    * This is necessary because Blender assumes that objects evaluate to an object data type, and
@@ -658,15 +701,15 @@ class CurveComponent : public GeometryComponent {
   GeometryComponent *copy() const override;
 
   void clear();
-  bool has_curve() const;
+  bool has_curves() const;
   /**
    * Clear the component and replace it with the new curve.
    */
-  void replace(CurveEval *curve, GeometryOwnershipType ownership = GeometryOwnershipType::Owned);
-  CurveEval *release();
+  void replace(Curves *curve, GeometryOwnershipType ownership = GeometryOwnershipType::Owned);
+  Curves *release();
 
-  const CurveEval *get_for_read() const;
-  CurveEval *get_for_write();
+  const Curves *get_for_read() const;
+  Curves *get_for_write();
 
   int attribute_domain_size(AttributeDomain domain) const final;
 
diff --git a/source/blender/blenkernel/BKE_spline.hh b/source/blender/blenkernel/BKE_spline.hh
index 439f20ee471..42b4702ee44 100644
--- a/source/blender/blenkernel/BKE_spline.hh
+++ b/source/blender/blenkernel/BKE_spline.hh
@@ -20,6 +20,7 @@
 #include "BKE_attribute_math.hh"
 
 struct Curve;
+struct Curves;
 struct ListBase;
 
 class Spline;
@@ -691,3 +692,5 @@ struct CurveEval {
 std::unique_ptr<CurveEval> curve_eval_from_dna_curve(const Curve &curve,
                                                      const ListBase &nurbs_list);
 std::unique_ptr<CurveEval> curve_eval_from_dna_curve(const Curve &dna_curve);
+std::unique_ptr<CurveEval> curves_to_curve_eval(const Curves &curves);
+Curves *curve_eval_to_curves(const CurveEval &curve_eval);
diff --git a/source/blender/blenkernel/CMakeLists.txt b/source/blender/blenkernel/CMakeLists.txt
index 2b77b2c5dae..a12a956cbf5 100644
--- a/source/blender/blenkernel/CMakeLists.txt
+++ b/source/blender/blenkernel/CMakeLists.txt
@@ -131,6 +131,7 @@ set(SRC
   intern/fmodifier.c
   intern/freestyle.c
   intern/geometry_component_curve.cc
+  intern/geometry_component_curves.cc
   intern/geometry_component_instances.cc
   intern/geometry_component_mesh.cc
   intern/geometry_component_pointcloud.cc
diff --git a/source/blender/blenkernel/intern/curve.cc b/source/blender/blenkernel/intern/curve.cc
index b0f58dd4ec9..6be04b79761 100644
--- a/source/blender/blenkernel/intern/curve.cc
+++ b/source/blender/blenkernel/intern/curve.cc
@@ -115,6 +115,8 @@ static void curve_free_data(ID *id)
   MEM_SAFE_FREE(curve->str);
   MEM_SAFE_FREE(curve->strinfo);
   MEM_SAFE_FREE(curve->tb);
+
+  delete curve->curve_eval;
 }
 
 static void curve_foreach_id(ID *id, LibraryForeachIDData *data)
diff --git a/source/blender/blenkernel/intern/curve_eval.cc b/source/blender/blenkernel/intern/curve_eval.cc
index 8529e7ad194..78dafe34b4f 100644
--- a/source/blender/blenkernel/intern/curve_eval.cc
+++ b/source/blender/blenkernel/intern/curve_eval.cc
@@ -13,6 +13,8 @@
 
 #include "BKE_anonymous_attribute.hh"
 #include "BKE_curve.h"
+#include "BKE_curves.hh"
+#include "BKE_geometry_set.hh"
 #include "BKE_spline.hh"
 
 using blender::Array;
@@ -23,8 +25,15 @@ using blender::Map;
 using blender::MutableSpan;
 using blender::Span;
 using blender::StringRefNull;
+using blender::VArray;
+using blender::VArray_Span;
 using blender::Vector;
 using blender::bke::AttributeIDRef;
+using blender::bke::OutputAttribute;
+using blender::bke::OutputAttribute_Typed;
+using blender::bke::ReadAttributeLookup;
+using blender::fn::GVArray;
+using blender::fn::GVArray_GSpan;
 
 blender::Span<SplinePtr> CurveEval::splines() const
 {
@@ -336,6 +345,186 @@ std::unique_ptr<CurveEval> curve_eval_from_dna_curve(const Curve &dna_curve)
   return curve_eval_from_dna_curve(dna_curve, *BKE_curve_nurbs_get_for_read(&dna_curve));
 }
 
+static void copy_attributes_between_components(const GeometryComponent &src_component,
+                                               GeometryComponent &dst_component,
+                                               Span<std::string> skip)
+{
+  src_component.attribute_foreach(
+      [&](const AttributeIDRef &id, const AttributeMetaData meta_data) {
+        if (id.is_named() && skip.contains(id.name())) {
+          return true;
+        }
+
+        GVArray src_attribute = src_component.attribute_try_get_for_read(
+            id, meta_data.domain, meta_data.data_type);
+        if (!src_attribute) {
+          return true;
+        }
+        GVArray_GSpan src_attribute_data{src_attribute};
+
+        OutputAttribute dst_attribute = dst_component.attribute_try_get_for_output_only(
+            id, meta_data.domain, meta_data.data_type);
+        if (!dst_attribute) {
+          return true;
+        }
+        dst_attribute.varray().set_all(src_attribute_data.data());
+        dst_attribute.save();
+        return true;
+      });
+}
+
+std::unique_ptr<CurveEval> curves_to_curve_eval(const Curves &curves)
+{
+  CurveComponent src_component;
+  src_component.replace(&const_cast<Curves &>(curves), GeometryOwnershipType::ReadOnly);
+  const blender::bke::CurvesGeometry &geometry = blender::bke::CurvesGeometry::wrap(
+      curves.geometry);
+
+  VArray_Span<float> nurbs_weights{
+      src_component.attribute_get_for_read<float>("nurbs_weight", ATTR_DOMAIN_POINT, 0.0f)};
+  VArray_Span<int> nurbs_orders{
+      src_component.attribute_get_for_read<int>("nurbs_order", ATTR_DOMAIN_CURVE, 4)};
+  VArray_Span<int8_t> nurbs_knots_modes{
+      src_component.attribute_get_for_read<int8_t>("knots_mode", ATTR_DOMAIN_CURVE, 0)};
+
+  VArray_Span<int8_t> handle_types_right{
+      src_component.attribute_get_for_read<int8_t>("handle_type_right", ATTR_DOMAIN_POINT, 0)};
+  VArray_Span<int8_t> handle_types_left{
+      src_component.attribute_get_for_read<int8_t>("handle_type_left", ATTR_DOMAIN_POINT, 0)};
+
+  /* Create splines with the correct size and type. */
+  VArray<int8_t> curve_types = geometry.curve_types();
+  std::unique_ptr<CurveEval> curve_eval = std::make_unique<CurveEval>();
+  for (const int curve_index : curve_types.index_range()) {
+    const IndexRange point_range = geometry.range

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list