Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source/blender/blenkernel/BKE_geometry_set.hh5
-rw-r--r--source/blender/blenkernel/intern/geometry_component_instances.cc83
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_set_position.cc7
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);