diff options
author | Erik <ecke101@gmail.com> | 2021-11-19 19:53:48 +0300 |
---|---|---|
committer | Erik <ecke101@gmail.com> | 2021-11-19 19:53:48 +0300 |
commit | 97533eede444217bd28df50a721707bdce340403 (patch) | |
tree | 0d3577b480ffd4b1c7f8030186b08ea95cb5d7b8 /source | |
parent | 9e3a913b35df9f9519d48e18223192a34ab8f22a (diff) |
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
Diffstat (limited to 'source')
7 files changed, 58 insertions, 19 deletions
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) { |