diff options
3 files changed, 92 insertions, 3 deletions
diff --git a/source/blender/blenkernel/BKE_geometry_set.hh b/source/blender/blenkernel/BKE_geometry_set.hh index bf38294257a..98f5de43f84 100644 --- a/source/blender/blenkernel/BKE_geometry_set.hh +++ b/source/blender/blenkernel/BKE_geometry_set.hh @@ -591,12 +591,17 @@ class InstancesComponent : public GeometryComponent { blender::Span<int> almost_unique_ids() const; + 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_INSTANCES; + + private: + const blender::bke::ComponentAttributeProviders *get_attribute_providers() const final; }; /** A geometry component that stores volume grids. */ diff --git a/source/blender/blenkernel/intern/geometry_component_instances.cc b/source/blender/blenkernel/intern/geometry_component_instances.cc index 26ef827d36d..c4e1fe2f8e9 100644 --- a/source/blender/blenkernel/intern/geometry_component_instances.cc +++ b/source/blender/blenkernel/intern/geometry_component_instances.cc @@ -25,6 +25,8 @@ #include "BKE_geometry_set.hh" +#include "attribute_access_intern.hh" + using blender::float4x4; using blender::Map; using blender::MutableSpan; @@ -225,4 +227,85 @@ blender::Span<int> InstancesComponent::almost_unique_ids() const return almost_unique_ids_; } +int InstancesComponent::attribute_domain_size(const AttributeDomain domain) const +{ + if (domain != ATTR_DOMAIN_POINT) { + return 0; + } + return this->instances_amount(); +} + +namespace blender::bke { + +static float3 get_transform_position(const float4x4 &transform) +{ + return transform.translation(); +} + +static void set_transform_position(float4x4 &transform, const float3 position) +{ + copy_v3_v3(transform.values[3], position); +} + +class InstancePositionAttributeProvider final : public BuiltinAttributeProvider { + public: + InstancePositionAttributeProvider() + : BuiltinAttributeProvider( + "position", ATTR_DOMAIN_POINT, CD_PROP_FLOAT3, NonCreatable, Writable, NonDeletable) + { + } + + GVArrayPtr try_get_for_read(const GeometryComponent &component) const final + { + const InstancesComponent &instances_component = static_cast<const InstancesComponent &>( + component); + Span<float4x4> transforms = instances_component.instance_transforms(); + return std::make_unique<fn::GVArray_For_DerivedSpan<float4x4, float3, get_transform_position>>( + transforms); + } + + GVMutableArrayPtr try_get_for_write(GeometryComponent &component) const final + { + InstancesComponent &instances_component = static_cast<InstancesComponent &>(component); + MutableSpan<float4x4> transforms = instances_component.instance_transforms(); + return std::make_unique<fn::GVMutableArray_For_DerivedSpan<float4x4, + float3, + get_transform_position, + set_transform_position>>( + transforms); + } + + bool try_delete(GeometryComponent &UNUSED(component)) const final + { + return false; + } + + bool try_create(GeometryComponent &UNUSED(component), + const AttributeInit &UNUSED(initializer)) const final + { + return false; + } + + bool exists(const GeometryComponent &UNUSED(component)) const final + { + return true; + } +}; + +static ComponentAttributeProviders create_attribute_providers_for_instances() +{ + static InstancePositionAttributeProvider position; + + return ComponentAttributeProviders({&position}, {}); +} +} // namespace blender::bke + +const blender::bke::ComponentAttributeProviders *InstancesComponent::get_attribute_providers() + const +{ + static blender::bke::ComponentAttributeProviders providers = + blender::bke::create_attribute_providers_for_instances(); + return &providers; +} + /** \} */ 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 4c754ddb643..832db76e731 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_set_position.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_set_position.cc @@ -51,12 +51,13 @@ static void set_position_in_component(GeometryComponent &component, static void geo_node_set_position_exec(GeoNodeExecParams params) { GeometrySet geometry = params.extract_input<GeometrySet>("Geometry"); - geometry = geometry_set_realize_instances(geometry); Field<bool> selection_field = params.extract_input<Field<bool>>("Selection"); Field<float3> position_field = params.extract_input<Field<float3>>("Position"); - for (const GeometryComponentType type : - {GEO_COMPONENT_TYPE_MESH, GEO_COMPONENT_TYPE_POINT_CLOUD, GEO_COMPONENT_TYPE_CURVE}) { + for (const GeometryComponentType type : {GEO_COMPONENT_TYPE_MESH, + GEO_COMPONENT_TYPE_POINT_CLOUD, + GEO_COMPONENT_TYPE_CURVE, + GEO_COMPONENT_TYPE_INSTANCES}) { if (geometry.has(type)) { set_position_in_component( geometry.get_component_for_write(type), selection_field, position_field); |