[Bf-blender-cvs] [d19176765db] cycles_texture_cache: Geometry Nodes: Initial basic curve data support

Hans Goudey noreply at git.blender.org
Thu May 6 11:25:39 CEST 2021


Commit: d19176765db8dc6dd644adaa7a13d47f4d294d6d
Author: Hans Goudey
Date:   Mon May 3 12:29:17 2021 -0500
Branches: cycles_texture_cache
https://developer.blender.org/rBd19176765db8dc6dd644adaa7a13d47f4d294d6d

Geometry Nodes: Initial basic curve data support

This patch adds initial curve support to geometry nodes. Currently
there is only one node available, the "Curve to Mesh" node, T87428.

However, the aim of the changes here is larger than just supporting
curve data in nodes-- it also uses the opportunity to add better spline
data structures, intended to replace the existing curve evaluation code.
The curve code in Blender is quite old, and it's generally regarded as
some of the messiest, hardest-to-understand code as well. The classes
in `BKE_spline.hh` aim to be faster, more extensible, and much more
easily understandable. Further explanation can be found in comments in
that file.

Initial builtin spline attributes are supported-- reading and writing
from the `cyclic` and `resolution` attributes works with any of the
attribute nodes. Also, only Z-up normal calculation is implemented
at the moment, and tilts do not apply yet.

**Limitations**
 - For now, you must bring curves into the node tree with an "Object
   Info" node. Changes to the curve modifier stack will come later.
 - Converting to a mesh is necessary to visualize the curve data.

Further progress can be tracked in: T87245
Higher level design document: https://wiki.blender.org/wiki/Modules/Physics_Nodes/Projects/EverythingNodes/CurveNodes

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

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

M	release/scripts/startup/nodeitems_builtins.py
M	source/blender/blenkernel/BKE_attribute_math.hh
M	source/blender/blenkernel/BKE_geometry_set.h
M	source/blender/blenkernel/BKE_geometry_set.hh
M	source/blender/blenkernel/BKE_node.h
A	source/blender/blenkernel/BKE_spline.hh
M	source/blender/blenkernel/CMakeLists.txt
M	source/blender/blenkernel/intern/DerivedMesh.cc
M	source/blender/blenkernel/intern/attribute_access.cc
A	source/blender/blenkernel/intern/curve_eval.cc
A	source/blender/blenkernel/intern/geometry_component_curve.cc
M	source/blender/blenkernel/intern/geometry_set.cc
M	source/blender/blenkernel/intern/geometry_set_instances.cc
M	source/blender/blenkernel/intern/node.cc
A	source/blender/blenkernel/intern/spline_base.cc
A	source/blender/blenkernel/intern/spline_bezier.cc
A	source/blender/blenkernel/intern/spline_nurbs.cc
A	source/blender/blenkernel/intern/spline_poly.cc
M	source/blender/blenlib/BLI_float3.hh
M	source/blender/blenlib/BLI_float4x4.hh
M	source/blender/makesrna/intern/rna_attribute.c
M	source/blender/makesrna/intern/rna_space.c
M	source/blender/modifiers/intern/MOD_nodes.cc
M	source/blender/nodes/CMakeLists.txt
M	source/blender/nodes/NOD_geometry.h
M	source/blender/nodes/NOD_static_types.h
M	source/blender/nodes/geometry/nodes/node_geo_align_rotation_to_vector.cc
M	source/blender/nodes/geometry/nodes/node_geo_attribute_clamp.cc
M	source/blender/nodes/geometry/nodes/node_geo_attribute_color_ramp.cc
M	source/blender/nodes/geometry/nodes/node_geo_attribute_combine_xyz.cc
M	source/blender/nodes/geometry/nodes/node_geo_attribute_compare.cc
M	source/blender/nodes/geometry/nodes/node_geo_attribute_convert.cc
M	source/blender/nodes/geometry/nodes/node_geo_attribute_fill.cc
M	source/blender/nodes/geometry/nodes/node_geo_attribute_map_range.cc
M	source/blender/nodes/geometry/nodes/node_geo_attribute_math.cc
M	source/blender/nodes/geometry/nodes/node_geo_attribute_mix.cc
M	source/blender/nodes/geometry/nodes/node_geo_attribute_proximity.cc
M	source/blender/nodes/geometry/nodes/node_geo_attribute_randomize.cc
M	source/blender/nodes/geometry/nodes/node_geo_attribute_remove.cc
M	source/blender/nodes/geometry/nodes/node_geo_attribute_sample_texture.cc
M	source/blender/nodes/geometry/nodes/node_geo_attribute_separate_xyz.cc
M	source/blender/nodes/geometry/nodes/node_geo_attribute_vector_math.cc
A	source/blender/nodes/geometry/nodes/node_geo_curve_to_mesh.cc
M	source/blender/nodes/geometry/nodes/node_geo_join_geometry.cc
M	source/blender/nodes/geometry/nodes/node_geo_point_instance.cc
M	source/blender/nodes/geometry/nodes/node_geo_points_to_volume.cc
M	source/blender/nodes/geometry/nodes/node_geo_transform.cc

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

diff --git a/release/scripts/startup/nodeitems_builtins.py b/release/scripts/startup/nodeitems_builtins.py
index 4584f799b95..379fa145c92 100644
--- a/release/scripts/startup/nodeitems_builtins.py
+++ b/release/scripts/startup/nodeitems_builtins.py
@@ -505,6 +505,9 @@ geometry_node_categories = [
         NodeItem("ShaderNodeSeparateRGB"),
         NodeItem("ShaderNodeCombineRGB"),
     ]),
+    GeometryNodeCategory("GEO_CURVE", "Curve", items=[
+        NodeItem("GeometryNodeCurveToMesh"),
+    ]),
     GeometryNodeCategory("GEO_GEOMETRY", "Geometry", items=[
         NodeItem("GeometryNodeBoundBox"),
         NodeItem("GeometryNodeTransform"),
diff --git a/source/blender/blenkernel/BKE_attribute_math.hh b/source/blender/blenkernel/BKE_attribute_math.hh
index fc7498951f9..b0d32b20d44 100644
--- a/source/blender/blenkernel/BKE_attribute_math.hh
+++ b/source/blender/blenkernel/BKE_attribute_math.hh
@@ -14,6 +14,8 @@
  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  */
 
+#pragma once
+
 #include "BLI_array.hh"
 #include "BLI_color.hh"
 #include "BLI_float2.hh"
diff --git a/source/blender/blenkernel/BKE_geometry_set.h b/source/blender/blenkernel/BKE_geometry_set.h
index c00310408af..cb5526cd690 100644
--- a/source/blender/blenkernel/BKE_geometry_set.h
+++ b/source/blender/blenkernel/BKE_geometry_set.h
@@ -36,6 +36,7 @@ typedef enum GeometryComponentType {
   GEO_COMPONENT_TYPE_POINT_CLOUD = 1,
   GEO_COMPONENT_TYPE_INSTANCES = 2,
   GEO_COMPONENT_TYPE_VOLUME = 3,
+  GEO_COMPONENT_TYPE_CURVE = 4,
 } GeometryComponentType;
 
 void BKE_geometry_set_free(struct GeometrySet *geometry_set);
diff --git a/source/blender/blenkernel/BKE_geometry_set.hh b/source/blender/blenkernel/BKE_geometry_set.hh
index 89cdef34297..2d0f099e5ce 100644
--- a/source/blender/blenkernel/BKE_geometry_set.hh
+++ b/source/blender/blenkernel/BKE_geometry_set.hh
@@ -39,6 +39,7 @@ struct Mesh;
 struct Object;
 struct PointCloud;
 struct Volume;
+class CurveEval;
 
 enum class GeometryOwnershipType {
   /* The geometry is owned. This implies that it can be changed. */
@@ -363,18 +364,25 @@ struct GeometrySet {
       Mesh *mesh, GeometryOwnershipType ownership = GeometryOwnershipType::Owned);
   static GeometrySet create_with_pointcloud(
       PointCloud *pointcloud, GeometryOwnershipType ownership = GeometryOwnershipType::Owned);
+  static GeometrySet create_with_curve(
+      CurveEval *curve, GeometryOwnershipType ownership = GeometryOwnershipType::Owned);
 
   /* Utility methods for access. */
   bool has_mesh() const;
   bool has_pointcloud() const;
   bool has_instances() const;
   bool has_volume() const;
+  bool has_curve() const;
+
   const Mesh *get_mesh_for_read() const;
   const PointCloud *get_pointcloud_for_read() const;
   const Volume *get_volume_for_read() const;
+  const CurveEval *get_curve_for_read() const;
+
   Mesh *get_mesh_for_write();
   PointCloud *get_pointcloud_for_write();
   Volume *get_volume_for_write();
+  CurveEval *get_curve_for_write();
 
   /* Utility methods for replacement. */
   void replace_mesh(Mesh *mesh, GeometryOwnershipType ownership = GeometryOwnershipType::Owned);
@@ -382,6 +390,8 @@ struct GeometrySet {
                           GeometryOwnershipType ownership = GeometryOwnershipType::Owned);
   void replace_volume(Volume *volume,
                       GeometryOwnershipType ownership = GeometryOwnershipType::Owned);
+  void replace_curve(CurveEval *curve,
+                     GeometryOwnershipType ownership = GeometryOwnershipType::Owned);
 };
 
 /** A geometry component that can store a mesh. */
@@ -463,6 +473,38 @@ class PointCloudComponent : public GeometryComponent {
   const blender::bke::ComponentAttributeProviders *get_attribute_providers() const final;
 };
 
+/** A geometry component that stores curve data, in other words, a group of splines. */
+class CurveComponent : public GeometryComponent {
+ private:
+  CurveEval *curve_ = nullptr;
+  GeometryOwnershipType ownership_ = GeometryOwnershipType::Owned;
+
+ public:
+  CurveComponent();
+  ~CurveComponent();
+  GeometryComponent *copy() const override;
+
+  void clear();
+  bool has_curve() const;
+  void replace(CurveEval *curve, GeometryOwnershipType ownership = GeometryOwnershipType::Owned);
+  CurveEval *release();
+
+  const CurveEval *get_for_read() const;
+  CurveEval *get_for_write();
+
+  int attribute_domain_size(const 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;
+};
+
 /** A geometry component that stores instances. */
 class InstancesComponent : public GeometryComponent {
  private:
diff --git a/source/blender/blenkernel/BKE_node.h b/source/blender/blenkernel/BKE_node.h
index 819c148f0ad..bcab456b36e 100644
--- a/source/blender/blenkernel/BKE_node.h
+++ b/source/blender/blenkernel/BKE_node.h
@@ -1418,6 +1418,7 @@ int ntreeTexExecTree(struct bNodeTree *ntree,
 #define GEO_NODE_BOUNDING_BOX 1042
 #define GEO_NODE_SWITCH 1043
 #define GEO_NODE_ATTRIBUTE_TRANSFER 1044
+#define GEO_NODE_CURVE_TO_MESH 1045
 
 /** \} */
 
diff --git a/source/blender/blenkernel/BKE_spline.hh b/source/blender/blenkernel/BKE_spline.hh
new file mode 100644
index 00000000000..5409eb52d02
--- /dev/null
+++ b/source/blender/blenkernel/BKE_spline.hh
@@ -0,0 +1,478 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#pragma once
+
+/** \file
+ * \ingroup bke
+ */
+
+#include <mutex>
+
+#include "FN_generic_virtual_array.hh"
+
+#include "BLI_float3.hh"
+#include "BLI_float4x4.hh"
+#include "BLI_vector.hh"
+
+#include "BKE_attribute_math.hh"
+
+struct Curve;
+
+class Spline;
+using SplinePtr = std::unique_ptr<Spline>;
+
+/**
+ * A spline is an abstraction of a single branch-less curve section, its evaluation methods,
+ * and data. The spline data itself is just control points and a set of attributes by the set
+ * of "evaluated" data is often used instead.
+ *
+ * Any derived class of Spline has to manage two things:
+ *  1. Interpolating arbitrary attribute data from the control points to evaluated points.
+ *  2. Evaluating the positions based on the stored control point data.
+ *
+ * Beyond that, everything is the base class's responsibility, with minor exceptions. Further
+ * evaluation happens in a layer on top of the evaluated points generated by the derived types.
+ *
+ * There are a few methods to evaluate a spline:
+ *  1. #evaluated_positions and #interpolate_to_evaluated_points give data at the initial
+ *     evaluated points, depending on the resolution.
+ *  2. #lookup_evaluated_factor and #lookup_evaluated_factor are meant for one-off lookups
+ *     along the length of a curve.
+ *
+ * Commonly used evaluated data is stored in caches on the spline itself so that operations on
+ * splines don't need to worry about taking ownership of evaluated data when they don't need to.
+ */
+class Spline {
+ public:
+  enum class Type {
+    Bezier,
+    NURBS,
+    Poly,
+  };
+
+ protected:
+  Type type_;
+  bool is_cyclic_ = false;
+
+ public:
+  enum NormalCalculationMode {
+    ZUp,
+    Minimum,
+    Tangent,
+  };
+  /* Only #Zup is supported at the moment. */
+  NormalCalculationMode normal_mode;
+
+ protected:
+  /** Direction of the spline at each evaluated point. */
+  mutable blender::Vector<blender::float3> evaluated_tangents_cache_;
+  mutable std::mutex tangent_cache_mutex_;
+  mutable bool tangent_cache_dirty_ = true;
+
+  /** Normal direction vectors for each evaluated point. */
+  mutable blender::Vector<blender::float3> evaluated_normals_cache_;
+  mutable std::mutex normal_cache_mutex_;
+  mutable bool normal_cache_dirty_ = true;
+
+  /** Accumulated lengths along the evaluated points. */
+  mutable blender::Vector<float> evaluated_lengths_cache_;
+  mutable std::mutex length_cache_mutex_;
+  mutable bool length_cache_dirty_ = true;
+
+ public:
+  virtual ~Spline() = default;
+  Spline(const Type type) : type_(type)
+  {
+  }
+  Spline(Spline &other)
+      : type_(other.type_), is_cyclic_(other.is_cyclic_), normal_mode(other.normal_mode)
+  {
+  }
+
+  virtual SplinePtr copy() const = 0;
+
+  Spline::Type type() const;
+
+  /** Return the number of control points. */
+  virtual int size() const = 0;
+  int segments_size() const;
+  bool is_cyclic() const;
+  void set_cyclic(const bool value);
+
+  virtual blender::MutableSpan<blender::float3> positions() = 0;
+  virtual blender::Span<blender::float3> positions() const = 0;
+  virtual blender::MutableSpan<float> radii() = 0;
+  virtual blender::Span<float> radii() const = 0;
+  virtual blender::MutableSpan<float> tilts() = 0;
+  virtual blender::Span<float> tilts() const = 0;
+
+  virtual void translate(const blender::float3 &translation);
+  virtual void transform(const blender::float4x4 &matrix);
+
+  /**
+   * Mark all caches for re-computation. This must be called after any operation that would
+   * change the generated positions, tangents, normals, mapping, etc. of the evaluated points.
+   */
+  virtual void mark_cache_invalid() = 0;
+  virtual int evaluated_points_size() const = 0;
+  int evaluated_edges_size() const;
+
+  float length() const;
+
+  virtual blender::Span<blender::float3> evaluated_positions() const = 0;
+
+  blender::Span<float> evaluated_lengths() const;
+  blender::Span<blender::float3> ev

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list