[Bf-blender-cvs] [97533eede44] master: Geometry Nodes: Support custom instance attributes

Erik noreply at git.blender.org
Fri Nov 19 17:55:26 CET 2021


Commit: 97533eede444217bd28df50a721707bdce340403
Author: Erik
Date:   Fri Nov 19 17:53:48 2021 +0100
Branches: master
https://developer.blender.org/rB97533eede444217bd28df50a721707bdce340403

Geometry Nodes: Support custom instance attributes

Adds an attribute provider for instance attributes.
A new domain `ATTR_DOMAIN_INSTANCE` is implemented.
Instance attributes are not yet realized correctly.

Differential Revision: D13149

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

M	source/blender/blenkernel/BKE_attribute.h
M	source/blender/blenkernel/BKE_geometry_set.hh
M	source/blender/blenkernel/intern/attribute_access.cc
M	source/blender/blenkernel/intern/geometry_component_instances.cc
M	source/blender/makesrna/intern/rna_attribute.c
M	source/blender/makesrna/intern/rna_space.c
M	source/blender/nodes/geometry/nodes/node_geo_set_position.cc

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

diff --git a/source/blender/blenkernel/BKE_attribute.h b/source/blender/blenkernel/BKE_attribute.h
index 7476474258b..2c83bef7517 100644
--- a/source/blender/blenkernel/BKE_attribute.h
+++ b/source/blender/blenkernel/BKE_attribute.h
@@ -43,12 +43,13 @@ struct ReportList;
  * Arrays may be initialized from this (e.g. #DATASET_layout_hierarchy).
  */
 typedef enum AttributeDomain {
-  ATTR_DOMAIN_AUTO = -1,  /* Use for nodes to choose automatically based on other data. */
-  ATTR_DOMAIN_POINT = 0,  /* Mesh, Hair or PointCloud Point */
-  ATTR_DOMAIN_EDGE = 1,   /* Mesh Edge */
-  ATTR_DOMAIN_FACE = 2,   /* Mesh Face */
-  ATTR_DOMAIN_CORNER = 3, /* Mesh Corner */
-  ATTR_DOMAIN_CURVE = 4,  /* Hair Curve */
+  ATTR_DOMAIN_AUTO = -1,    /* Use for nodes to choose automatically based on other data. */
+  ATTR_DOMAIN_POINT = 0,    /* Mesh, Hair or PointCloud Point */
+  ATTR_DOMAIN_EDGE = 1,     /* Mesh Edge */
+  ATTR_DOMAIN_FACE = 2,     /* Mesh Face */
+  ATTR_DOMAIN_CORNER = 3,   /* Mesh Corner */
+  ATTR_DOMAIN_CURVE = 4,    /* Hair Curve */
+  ATTR_DOMAIN_INSTANCE = 5, /* Instance */
 
   ATTR_DOMAIN_NUM
 } AttributeDomain;
diff --git a/source/blender/blenkernel/BKE_geometry_set.hh b/source/blender/blenkernel/BKE_geometry_set.hh
index 63ada807c55..35e66908d54 100644
--- a/source/blender/blenkernel/BKE_geometry_set.hh
+++ b/source/blender/blenkernel/BKE_geometry_set.hh
@@ -651,6 +651,8 @@ class InstancesComponent : public GeometryComponent {
   mutable std::mutex almost_unique_ids_mutex_;
   mutable blender::Array<int> almost_unique_ids_;
 
+  blender::bke::CustomDataAttributes attributes_;
+
  public:
   InstancesComponent();
   ~InstancesComponent() = default;
@@ -685,6 +687,9 @@ class InstancesComponent : public GeometryComponent {
 
   blender::Span<int> almost_unique_ids() const;
 
+  blender::bke::CustomDataAttributes &attributes();
+  const blender::bke::CustomDataAttributes &attributes() const;
+
   int attribute_domain_size(const AttributeDomain domain) const final;
 
   void foreach_referenced_geometry(
diff --git a/source/blender/blenkernel/intern/attribute_access.cc b/source/blender/blenkernel/intern/attribute_access.cc
index f3ece270618..3f2c1f13337 100644
--- a/source/blender/blenkernel/intern/attribute_access.cc
+++ b/source/blender/blenkernel/intern/attribute_access.cc
@@ -164,16 +164,18 @@ CustomDataType attribute_data_type_highest_complexity(Span<CustomDataType> data_
 static int attribute_domain_priority(const AttributeDomain domain)
 {
   switch (domain) {
-    case ATTR_DOMAIN_CURVE:
+    case ATTR_DOMAIN_INSTANCE:
       return 0;
-    case ATTR_DOMAIN_FACE:
+    case ATTR_DOMAIN_CURVE:
       return 1;
-    case ATTR_DOMAIN_EDGE:
+    case ATTR_DOMAIN_FACE:
       return 2;
-    case ATTR_DOMAIN_POINT:
+    case ATTR_DOMAIN_EDGE:
       return 3;
-    case ATTR_DOMAIN_CORNER:
+    case ATTR_DOMAIN_POINT:
       return 4;
+    case ATTR_DOMAIN_CORNER:
+      return 5;
     default:
       /* Domain not supported in nodes yet. */
       BLI_assert_unreachable();
@@ -1448,6 +1450,7 @@ static StringRef get_random_id_attribute_name(const AttributeDomain domain)
 {
   switch (domain) {
     case ATTR_DOMAIN_POINT:
+    case ATTR_DOMAIN_INSTANCE:
       return "id";
     default:
       return "";
diff --git a/source/blender/blenkernel/intern/geometry_component_instances.cc b/source/blender/blenkernel/intern/geometry_component_instances.cc
index 047bceda4fe..9a30c86c1e5 100644
--- a/source/blender/blenkernel/intern/geometry_component_instances.cc
+++ b/source/blender/blenkernel/intern/geometry_component_instances.cc
@@ -363,12 +363,22 @@ blender::Span<int> InstancesComponent::almost_unique_ids() const
 
 int InstancesComponent::attribute_domain_size(const AttributeDomain domain) const
 {
-  if (domain != ATTR_DOMAIN_POINT) {
+  if (domain != ATTR_DOMAIN_INSTANCE) {
     return 0;
   }
   return this->instances_amount();
 }
 
+blender::bke::CustomDataAttributes &InstancesComponent::attributes()
+{
+  return this->attributes_;
+}
+
+const blender::bke::CustomDataAttributes &InstancesComponent::attributes() const
+{
+  return this->attributes_;
+}
+
 namespace blender::bke {
 
 static float3 get_transform_position(const float4x4 &transform)
@@ -385,7 +395,7 @@ class InstancePositionAttributeProvider final : public BuiltinAttributeProvider
  public:
   InstancePositionAttributeProvider()
       : BuiltinAttributeProvider(
-            "position", ATTR_DOMAIN_POINT, CD_PROP_FLOAT3, NonCreatable, Writable, NonDeletable)
+            "position", ATTR_DOMAIN_INSTANCE, CD_PROP_FLOAT3, NonCreatable, Writable, NonDeletable)
   {
   }
 
@@ -428,7 +438,7 @@ class InstanceIDAttributeProvider final : public BuiltinAttributeProvider {
  public:
   InstanceIDAttributeProvider()
       : BuiltinAttributeProvider(
-            "id", ATTR_DOMAIN_POINT, CD_PROP_INT32, Creatable, Writable, Deletable)
+            "id", ATTR_DOMAIN_INSTANCE, CD_PROP_INT32, Creatable, Writable, Deletable)
   {
   }
 
@@ -499,7 +509,21 @@ static ComponentAttributeProviders create_attribute_providers_for_instances()
   static InstancePositionAttributeProvider position;
   static InstanceIDAttributeProvider id;
 
-  return ComponentAttributeProviders({&position, &id}, {});
+  static CustomDataAccessInfo instance_custom_data_access = {
+      [](GeometryComponent &component) -> CustomData * {
+        InstancesComponent &inst = static_cast<InstancesComponent &>(component);
+        return &inst.attributes().data;
+      },
+      [](const GeometryComponent &component) -> const CustomData * {
+        const InstancesComponent &inst = static_cast<const InstancesComponent &>(component);
+        return &inst.attributes().data;
+      },
+      nullptr};
+
+  static CustomDataAttributeProvider instance_custom_data(ATTR_DOMAIN_INSTANCE,
+                                                          instance_custom_data_access);
+
+  return ComponentAttributeProviders({&position, &id}, {&instance_custom_data});
 }
 }  // namespace blender::bke
 
diff --git a/source/blender/makesrna/intern/rna_attribute.c b/source/blender/makesrna/intern/rna_attribute.c
index dbf20896463..78c15444308 100644
--- a/source/blender/makesrna/intern/rna_attribute.c
+++ b/source/blender/makesrna/intern/rna_attribute.c
@@ -72,6 +72,7 @@ const EnumPropertyItem rna_enum_attribute_domain_items[] = {
     /* Not implement yet */
     // {ATTR_DOMAIN_GRIDS, "GRIDS", 0, "Grids", "Attribute on mesh multires grids"},
     {ATTR_DOMAIN_CURVE, "CURVE", 0, "Spline", "Attribute on spline"},
+    {ATTR_DOMAIN_INSTANCE, "INSTANCE", 0, "Instance", "Attribute on instance"},
     {0, NULL, 0, NULL, NULL},
 };
 
@@ -80,6 +81,7 @@ const EnumPropertyItem rna_enum_attribute_domain_without_corner_items[] = {
     {ATTR_DOMAIN_EDGE, "EDGE", 0, "Edge", "Attribute on mesh edge"},
     {ATTR_DOMAIN_FACE, "FACE", 0, "Face", "Attribute on mesh faces"},
     {ATTR_DOMAIN_CURVE, "CURVE", 0, "Spline", "Attribute on spline"},
+    {ATTR_DOMAIN_INSTANCE, "INSTANCE", 0, "Instance", "Attribute on instance"},
     {0, NULL, 0, NULL, NULL},
 };
 
@@ -90,6 +92,7 @@ const EnumPropertyItem rna_enum_attribute_domain_with_auto_items[] = {
     {ATTR_DOMAIN_FACE, "FACE", 0, "Face", "Attribute on mesh faces"},
     {ATTR_DOMAIN_CORNER, "CORNER", 0, "Face Corner", "Attribute on mesh face corner"},
     {ATTR_DOMAIN_CURVE, "CURVE", 0, "Spline", "Attribute on spline"},
+    {ATTR_DOMAIN_INSTANCE, "INSTANCE", 0, "Instance", "Attribute on instance"},
     {0, NULL, 0, NULL, NULL},
 };
 
diff --git a/source/blender/makesrna/intern/rna_space.c b/source/blender/makesrna/intern/rna_space.c
index 03976967e9f..e7bcd387eaf 100644
--- a/source/blender/makesrna/intern/rna_space.c
+++ b/source/blender/makesrna/intern/rna_space.c
@@ -3090,7 +3090,7 @@ static void rna_SpaceSpreadsheet_geometry_component_type_update(Main *UNUSED(bma
       break;
     }
     case GEO_COMPONENT_TYPE_INSTANCES: {
-      sspreadsheet->attribute_domain = ATTR_DOMAIN_POINT;
+      sspreadsheet->attribute_domain = ATTR_DOMAIN_INSTANCE;
       break;
     }
     case GEO_COMPONENT_TYPE_VOLUME: {
diff --git a/source/blender/nodes/geometry/nodes/node_geo_set_position.cc b/source/blender/nodes/geometry/nodes/node_geo_set_position.cc
index 4e564386a28..5fe9fb1b3d4 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_set_position.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_set_position.cc
@@ -34,8 +34,11 @@ static void set_position_in_component(GeometryComponent &component,
                                       const Field<float3> &position_field,
                                       const Field<float3> &offset_field)
 {
-  GeometryComponentFieldContext field_context{component, ATTR_DOMAIN_POINT};
-  const int domain_size = component.attribute_domain_size(ATTR_DOMAIN_POINT);
+  AttributeDomain domain = component.type() == GEO_COMPONENT_TYPE_INSTANCES ?
+                               ATTR_DOMAIN_INSTANCE :
+                               ATTR_DOMAIN_POINT;
+  GeometryComponentFieldContext field_context{component, domain};
+  const int domain_size = component.attribute_domain_size(domain);
   if (domain_size == 0) {
     return;
   }
@@ -57,7 +60,7 @@ static void set_position_in_component(GeometryComponent &component,
   const VArray<float3> &offsets_input = position_evaluator.get_evaluated<float3>(1);
 
   OutputAttribute_Typed<float3> positions = component.attribute_try_get_for_output<float3>(
-      "position", ATTR_DOMAIN_POINT, {0, 0, 0});
+      "position", domain, {0, 0, 0});
   MutableSpan<float3> position_mutable = positions.as_span();
 
   for (int i : selection) {



More information about the Bf-blender-cvs mailing list