diff options
author | Jacques Lucke <jacques@blender.org> | 2021-09-20 13:49:11 +0300 |
---|---|---|
committer | Jacques Lucke <jacques@blender.org> | 2021-09-20 13:49:28 +0300 |
commit | 8c7c4549d1fba8eb2236fa397d95b32ad1262789 (patch) | |
tree | 3d22e7b87086722a8ce031fcc0daf821373192f9 /source/blender/blenkernel | |
parent | 11e11c41f2695f6f412079d438b675516aa8151a (diff) |
Geometry Nodes: support Set Position node on instances
Previously, the node would always realize instances implicitly.
Now it can change the position of entire instances.
The Realize Instances node can be used before if the old
behavior is required.
Differential Revision: https://developer.blender.org/D12555
Diffstat (limited to 'source/blender/blenkernel')
-rw-r--r-- | source/blender/blenkernel/BKE_geometry_set.hh | 5 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/geometry_component_instances.cc | 83 |
2 files changed, 88 insertions, 0 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; +} + /** \} */ |