[Bf-blender-cvs] [82a46ea6f88] master: Geometry Nodes: Use separate field context for each geometry type

Hans Goudey noreply at git.blender.org
Tue Aug 30 18:11:08 CEST 2022


Commit: 82a46ea6f8829fc40205d0d3cabf4017eb738d9a
Author: Hans Goudey
Date:   Tue Aug 30 11:08:27 2022 -0500
Branches: master
https://developer.blender.org/rB82a46ea6f8829fc40205d0d3cabf4017eb738d9a

Geometry Nodes: Use separate field context for each geometry type

Using the same `GeometryComponentFieldContext` for all situations,
even when only one geometry type is supported is misleading, and mixes
too many different abstraction levels into code that could be simpler.
With the attribute API moved out of geometry components recently,
the "component" system is just getting in the way here.

This commit adds specific field contexts for geometry types: meshes,
curves, point clouds, and instances. There are also separate field input
helper classes, to help reduce boilerplate for fields that only support
specific geometry types.

Another benefit of this change is that it separates geometry components
from fields, which makes it easier to see the purpose of the two concepts,
and how they relate.

Because we want to be able to evaluate a field on just `CurvesGeometry`
rather than the full `Curves` data-block, the generic "geometry context"
had to be changed to avoid using `GeometryComponent`, since there is
no corresponding geometry component type. The resulting void pointer
is ugly, but only turns up in three places in practice. When Apple clang
supports `std::variant`, that could be used instead.

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

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

M	source/blender/blenkernel/BKE_attribute.hh
M	source/blender/blenkernel/BKE_geometry_fields.hh
M	source/blender/blenkernel/CMakeLists.txt
M	source/blender/blenkernel/intern/attribute_access.cc
M	source/blender/blenkernel/intern/geometry_component_curves.cc
M	source/blender/blenkernel/intern/geometry_component_mesh.cc
A	source/blender/blenkernel/intern/geometry_fields.cc
M	source/blender/blenkernel/intern/geometry_set.cc
M	source/blender/editors/space_spreadsheet/spreadsheet_data_source_geometry.cc
M	source/blender/geometry/GEO_resample_curves.hh
M	source/blender/geometry/intern/resample_curves.cc
M	source/blender/modifiers/intern/MOD_nodes.cc
M	source/blender/nodes/NOD_geometry_exec.hh
M	source/blender/nodes/geometry/nodes/node_geo_accumulate_field.cc
M	source/blender/nodes/geometry/nodes/node_geo_attribute_capture.cc
M	source/blender/nodes/geometry/nodes/node_geo_attribute_statistic.cc
M	source/blender/nodes/geometry/nodes/node_geo_curve_endpoint_selection.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_resample.cc
M	source/blender/nodes/geometry/nodes/node_geo_curve_reverse.cc
M	source/blender/nodes/geometry/nodes/node_geo_curve_set_handle_type.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_trim.cc
M	source/blender/nodes/geometry/nodes/node_geo_delete_geometry.cc
M	source/blender/nodes/geometry/nodes/node_geo_distribute_points_on_faces.cc
M	source/blender/nodes/geometry/nodes/node_geo_duplicate_elements.cc
M	source/blender/nodes/geometry/nodes/node_geo_edge_paths_to_curves.cc
M	source/blender/nodes/geometry/nodes/node_geo_edge_paths_to_selection.cc
M	source/blender/nodes/geometry/nodes/node_geo_edge_split.cc
M	source/blender/nodes/geometry/nodes/node_geo_extrude_mesh.cc
M	source/blender/nodes/geometry/nodes/node_geo_field_at_index.cc
M	source/blender/nodes/geometry/nodes/node_geo_flip_faces.cc
M	source/blender/nodes/geometry/nodes/node_geo_input_curve_handles.cc
M	source/blender/nodes/geometry/nodes/node_geo_input_instance_rotation.cc
M	source/blender/nodes/geometry/nodes/node_geo_input_instance_scale.cc
M	source/blender/nodes/geometry/nodes/node_geo_input_mesh_edge_angle.cc
M	source/blender/nodes/geometry/nodes/node_geo_input_mesh_edge_neighbors.cc
M	source/blender/nodes/geometry/nodes/node_geo_input_mesh_edge_vertices.cc
M	source/blender/nodes/geometry/nodes/node_geo_input_mesh_face_area.cc
M	source/blender/nodes/geometry/nodes/node_geo_input_mesh_face_is_planar.cc
M	source/blender/nodes/geometry/nodes/node_geo_input_mesh_face_neighbors.cc
M	source/blender/nodes/geometry/nodes/node_geo_input_mesh_island.cc
M	source/blender/nodes/geometry/nodes/node_geo_input_mesh_vertex_neighbors.cc
M	source/blender/nodes/geometry/nodes/node_geo_input_shortest_edge_paths.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_instance_on_points.cc
M	source/blender/nodes/geometry/nodes/node_geo_instances_to_points.cc
M	source/blender/nodes/geometry/nodes/node_geo_interpolate_domain.cc
M	source/blender/nodes/geometry/nodes/node_geo_material_selection.cc
M	source/blender/nodes/geometry/nodes/node_geo_merge_by_distance.cc
M	source/blender/nodes/geometry/nodes/node_geo_mesh_to_curve.cc
M	source/blender/nodes/geometry/nodes/node_geo_mesh_to_points.cc
M	source/blender/nodes/geometry/nodes/node_geo_points_to_vertices.cc
M	source/blender/nodes/geometry/nodes/node_geo_points_to_volume.cc
M	source/blender/nodes/geometry/nodes/node_geo_raycast.cc
M	source/blender/nodes/geometry/nodes/node_geo_rotate_instances.cc
M	source/blender/nodes/geometry/nodes/node_geo_scale_elements.cc
M	source/blender/nodes/geometry/nodes/node_geo_scale_instances.cc
M	source/blender/nodes/geometry/nodes/node_geo_set_curve_handles.cc
M	source/blender/nodes/geometry/nodes/node_geo_set_curve_radius.cc
M	source/blender/nodes/geometry/nodes/node_geo_set_curve_tilt.cc
M	source/blender/nodes/geometry/nodes/node_geo_set_id.cc
M	source/blender/nodes/geometry/nodes/node_geo_set_material.cc
M	source/blender/nodes/geometry/nodes/node_geo_set_material_index.cc
M	source/blender/nodes/geometry/nodes/node_geo_set_point_radius.cc
M	source/blender/nodes/geometry/nodes/node_geo_set_position.cc
M	source/blender/nodes/geometry/nodes/node_geo_set_shade_smooth.cc
M	source/blender/nodes/geometry/nodes/node_geo_set_spline_cyclic.cc
M	source/blender/nodes/geometry/nodes/node_geo_set_spline_resolution.cc
M	source/blender/nodes/geometry/nodes/node_geo_store_named_attribute.cc
M	source/blender/nodes/geometry/nodes/node_geo_subdivision_surface.cc
M	source/blender/nodes/geometry/nodes/node_geo_transfer_attribute.cc
M	source/blender/nodes/geometry/nodes/node_geo_translate_instances.cc
M	source/blender/nodes/geometry/nodes/node_geo_triangulate.cc
M	source/blender/nodes/geometry/nodes/node_geo_uv_pack_islands.cc
M	source/blender/nodes/geometry/nodes/node_geo_uv_unwrap.cc

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

diff --git a/source/blender/blenkernel/BKE_attribute.hh b/source/blender/blenkernel/BKE_attribute.hh
index d29c60a7373..c2f65c93cbe 100644
--- a/source/blender/blenkernel/BKE_attribute.hh
+++ b/source/blender/blenkernel/BKE_attribute.hh
@@ -2,6 +2,8 @@
 
 #pragma once
 
+#include <optional>
+
 #include "BLI_color.hh"
 #include "BLI_function_ref.hh"
 #include "BLI_generic_span.hh"
diff --git a/source/blender/blenkernel/BKE_geometry_fields.hh b/source/blender/blenkernel/BKE_geometry_fields.hh
index 7c504826044..0e9bf700320 100644
--- a/source/blender/blenkernel/BKE_geometry_fields.hh
+++ b/source/blender/blenkernel/BKE_geometry_fields.hh
@@ -12,43 +12,181 @@
 
 #include "FN_field.hh"
 
+struct Mesh;
+struct PointCloud;
+
 namespace blender::bke {
 
-class GeometryComponentFieldContext : public fn::FieldContext {
+struct CurvesGeometry;
+class GeometryFieldInput;
+
+class MeshFieldContext : public fn::FieldContext {
+ private:
+  const Mesh &mesh_;
+  const eAttrDomain domain_;
+
+ public:
+  MeshFieldContext(const Mesh &mesh, const eAttrDomain domain);
+  const Mesh &mesh() const
+  {
+    return mesh_;
+  }
+
+  eAttrDomain domain() const
+  {
+    return domain_;
+  }
+};
+
+class CurvesFieldContext : public fn::FieldContext {
+ private:
+  const CurvesGeometry &curves_;
+  const eAttrDomain domain_;
+
+ public:
+  CurvesFieldContext(const CurvesGeometry &curves, const eAttrDomain domain);
+
+  const CurvesGeometry &curves() const
+  {
+    return curves_;
+  }
+
+  eAttrDomain domain() const
+  {
+    return domain_;
+  }
+};
+
+class PointCloudFieldContext : public fn::FieldContext {
+ private:
+  const PointCloud &pointcloud_;
+
+ public:
+  PointCloudFieldContext(const PointCloud &pointcloud) : pointcloud_(pointcloud)
+  {
+  }
+
+  const PointCloud &pointcloud() const
+  {
+    return pointcloud_;
+  }
+};
+
+class InstancesFieldContext : public fn::FieldContext {
+ private:
+  const InstancesComponent &instances_;
+
+ public:
+  InstancesFieldContext(const InstancesComponent &instances) : instances_(instances)
+  {
+  }
+
+  const InstancesComponent &instances() const
+  {
+    return instances_;
+  }
+};
+
+/**
+ * A field context that can represent meshes, curves, point clouds, or instances,
+ * used for field inputs that can work for multiple geometry types.
+ */
+class GeometryFieldContext : public fn::FieldContext {
  private:
-  const GeometryComponent &component_;
+  /**
+   * Store the geometry as a void pointer instead of a #GeometryComponent to allow referencing data
+   * that doesn't correspond directly to a geometry component type, in this case #CurvesGeometry
+   * instead of #Curves.
+   */
+  const void *geometry_;
+  const GeometryComponentType type_;
   const eAttrDomain domain_;
 
+  friend GeometryFieldInput;
+
  public:
-  GeometryComponentFieldContext(const GeometryComponent &component, const eAttrDomain domain)
-      : component_(component), domain_(domain)
+  GeometryFieldContext(const GeometryComponent &component, eAttrDomain domain);
+  GeometryFieldContext(const void *geometry, GeometryComponentType type, eAttrDomain domain);
+
+  const void *geometry() const
   {
+    return geometry_;
   }
 
-  const GeometryComponent &geometry_component() const
+  GeometryComponentType type() const
   {
-    return component_;
+    return type_;
   }
 
   eAttrDomain domain() const
   {
     return domain_;
   }
+
+  std::optional<AttributeAccessor> attributes() const;
+  const Mesh *mesh() const;
+  const CurvesGeometry *curves() const;
+  const PointCloud *pointcloud() const;
+  const InstancesComponent *instances() const;
+
+ private:
+  GeometryFieldContext(const Mesh &mesh, eAttrDomain domain);
+  GeometryFieldContext(const CurvesGeometry &curves, eAttrDomain domain);
+  GeometryFieldContext(const PointCloud &points);
+  GeometryFieldContext(const InstancesComponent &instances);
 };
 
 class GeometryFieldInput : public fn::FieldInput {
  public:
   using fn::FieldInput::FieldInput;
+  GVArray get_varray_for_context(const fn::FieldContext &context,
+                                 IndexMask mask,
+                                 ResourceScope &scope) const override;
+  virtual GVArray get_varray_for_context(const GeometryFieldContext &context,
+                                         IndexMask mask) const = 0;
+};
 
+class MeshFieldInput : public fn::FieldInput {
+ public:
+  using fn::FieldInput::FieldInput;
   GVArray get_varray_for_context(const fn::FieldContext &context,
                                  IndexMask mask,
                                  ResourceScope &scope) const override;
+  virtual GVArray get_varray_for_context(const Mesh &mesh,
+                                         eAttrDomain domain,
+                                         IndexMask mask) const = 0;
+};
 
-  virtual GVArray get_varray_for_context(const GeometryComponent &component,
+class CurvesFieldInput : public fn::FieldInput {
+ public:
+  using fn::FieldInput::FieldInput;
+  GVArray get_varray_for_context(const fn::FieldContext &context,
+                                 IndexMask mask,
+                                 ResourceScope &scope) const override;
+  virtual GVArray get_varray_for_context(const CurvesGeometry &curves,
                                          eAttrDomain domain,
                                          IndexMask mask) const = 0;
 };
 
+class PointCloudFieldInput : public fn::FieldInput {
+ public:
+  using fn::FieldInput::FieldInput;
+  GVArray get_varray_for_context(const fn::FieldContext &context,
+                                 IndexMask mask,
+                                 ResourceScope &scope) const override;
+  virtual GVArray get_varray_for_context(const PointCloud &pointcloud, IndexMask mask) const = 0;
+};
+
+class InstancesFieldInput : public fn::FieldInput {
+ public:
+  using fn::FieldInput::FieldInput;
+  GVArray get_varray_for_context(const fn::FieldContext &context,
+                                 IndexMask mask,
+                                 ResourceScope &scope) const override;
+  virtual GVArray get_varray_for_context(const InstancesComponent &instances,
+                                         IndexMask mask) const = 0;
+};
+
 class AttributeFieldInput : public GeometryFieldInput {
  private:
   std::string name_;
@@ -72,8 +210,7 @@ class AttributeFieldInput : public GeometryFieldInput {
     return name_;
   }
 
-  GVArray get_varray_for_context(const GeometryComponent &component,
-                                 eAttrDomain domain,
+  GVArray get_varray_for_context(const GeometryFieldContext &context,
                                  IndexMask mask) const override;
 
   std::string socket_inspection_name() const override;
@@ -89,8 +226,7 @@ class IDAttributeFieldInput : public GeometryFieldInput {
     category_ = Category::Generated;
   }
 
-  GVArray get_varray_for_context(const GeometryComponent &component,
-                                 eAttrDomain domain,
+  GVArray get_varray_for_context(const GeometryFieldContext &context,
                                  IndexMask mask) const override;
 
   std::string socket_inspection_name() const override;
@@ -99,12 +235,9 @@ class IDAttributeFieldInput : public GeometryFieldInput {
   bool is_equal_to(const fn::FieldNode &other) const override;
 };
 
-VArray<float3> curve_normals_varray(const CurveComponent &component, const eAttrDomain domain);
+VArray<float3> curve_normals_varray(const CurvesGeometry &curves, const eAttrDomain domain);
 
-VArray<float3> mesh_normals_varray(const MeshComponent &mesh_component,
-                                   const Mesh &mesh,
-                                   const IndexMask mask,
-                                   eAttrDomain domain);
+VArray<float3> mesh_normals_varray(const Mesh &mesh, const IndexMask mask, eAttrDomain domain);
 
 class NormalFieldInput : public GeometryFieldInput {
  public:
@@ -113,8 +246,7 @@ class NormalFieldInput : public GeometryFieldInput {
     category_ = Category::Generated;
   }
 
-  GVArray get_varray_for_context(const GeometryComponent &component,
-                                 const eAttrDomain domain,
+  GVArray get_varray_for_context(const GeometryFieldContext &context,
                                  IndexMask mask) const override;
 
   std::string socket_inspection_name() const override;
@@ -152,8 +284,7 @@ class AnonymousAttributeFieldInput : public GeometryFieldInput {
     return fn::Field<T>{field_input};
   }
 
-  GVArray get_varray_for_context(const GeometryComponent &component,
-                                 eAttrDomain domain,
+  GVArray get_varray_for_context(const GeometryFieldContext &context,
                                  IndexMask mask) const override;
 
   std::string socket_inspection_name() const override;
@@ -162,10 +293,10 @@ class AnonymousAttributeFieldInput : public GeometryFieldInput {
   bool is_equal_to(const fn::FieldNode &other) const override;
 };
 
-class CurveLengthFieldInput final : public GeometryFieldInput {
+class CurveLengthFieldInput final : public CurvesFieldInput {
  public:
   CurveLengthFieldInput();
-  GVArray get_varray_for_context(const GeometryComponent &component,
+  GVArray get_varray_for_context(const CurvesGeometry &curves,
                                  eAttrDomain domain,
                                  IndexMask mask) const final;
   uint64_t hash() const override;
diff --git a/source/blender/blenkernel/CMakeLists.txt b/source/blender/blenkernel/CMakeLists.txt
index 8b7fbc4938f..465573745ec 100644
--- a/source/blender/blenkernel/CMakeLists.txt
+++ b/source/blender/blenkernel/CMakeLists.txt
@@ -143,6 +143,7 @@ set(SRC
   intern/geometry_component_mesh.cc
   intern/geometry_component_pointcloud.cc
   intern/geometry_component_volume.cc
+  intern/geometry_fields.cc
   intern/geometry_set.cc
   intern/geometry_set_instances.cc
   intern/gpencil.c
diff --git a/source/blender/blenkernel/intern/attribute_access.cc b/source/blender/blenkernel/intern/attribute_access.cc
index b9995796a21..313e6a172ac 100644
--- a/source/blender/blenkernel/intern/attribute_access.cc
+++ b/source/blender/blenkernel/intern/attribute_access.cc
@@ -5,7 +5,6 @@
 #include "BKE_attribute_math.hh"
 #include "B

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list