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
This commit is contained in:
@@ -43,12 +43,13 @@ struct ReportList;
|
|||||||
* Arrays may be initialized from this (e.g. #DATASET_layout_hierarchy).
|
* Arrays may be initialized from this (e.g. #DATASET_layout_hierarchy).
|
||||||
*/
|
*/
|
||||||
typedef enum AttributeDomain {
|
typedef enum AttributeDomain {
|
||||||
ATTR_DOMAIN_AUTO = -1, /* Use for nodes to choose automatically based on other data. */
|
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_POINT = 0, /* Mesh, Hair or PointCloud Point */
|
||||||
ATTR_DOMAIN_EDGE = 1, /* Mesh Edge */
|
ATTR_DOMAIN_EDGE = 1, /* Mesh Edge */
|
||||||
ATTR_DOMAIN_FACE = 2, /* Mesh Face */
|
ATTR_DOMAIN_FACE = 2, /* Mesh Face */
|
||||||
ATTR_DOMAIN_CORNER = 3, /* Mesh Corner */
|
ATTR_DOMAIN_CORNER = 3, /* Mesh Corner */
|
||||||
ATTR_DOMAIN_CURVE = 4, /* Hair Curve */
|
ATTR_DOMAIN_CURVE = 4, /* Hair Curve */
|
||||||
|
ATTR_DOMAIN_INSTANCE = 5, /* Instance */
|
||||||
|
|
||||||
ATTR_DOMAIN_NUM
|
ATTR_DOMAIN_NUM
|
||||||
} AttributeDomain;
|
} AttributeDomain;
|
||||||
|
|||||||
@@ -651,6 +651,8 @@ class InstancesComponent : public GeometryComponent {
|
|||||||
mutable std::mutex almost_unique_ids_mutex_;
|
mutable std::mutex almost_unique_ids_mutex_;
|
||||||
mutable blender::Array<int> almost_unique_ids_;
|
mutable blender::Array<int> almost_unique_ids_;
|
||||||
|
|
||||||
|
blender::bke::CustomDataAttributes attributes_;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
InstancesComponent();
|
InstancesComponent();
|
||||||
~InstancesComponent() = default;
|
~InstancesComponent() = default;
|
||||||
@@ -685,6 +687,9 @@ class InstancesComponent : public GeometryComponent {
|
|||||||
|
|
||||||
blender::Span<int> almost_unique_ids() const;
|
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;
|
int attribute_domain_size(const AttributeDomain domain) const final;
|
||||||
|
|
||||||
void foreach_referenced_geometry(
|
void foreach_referenced_geometry(
|
||||||
|
|||||||
@@ -164,16 +164,18 @@ CustomDataType attribute_data_type_highest_complexity(Span<CustomDataType> data_
|
|||||||
static int attribute_domain_priority(const AttributeDomain domain)
|
static int attribute_domain_priority(const AttributeDomain domain)
|
||||||
{
|
{
|
||||||
switch (domain) {
|
switch (domain) {
|
||||||
case ATTR_DOMAIN_CURVE:
|
case ATTR_DOMAIN_INSTANCE:
|
||||||
return 0;
|
return 0;
|
||||||
case ATTR_DOMAIN_FACE:
|
case ATTR_DOMAIN_CURVE:
|
||||||
return 1;
|
return 1;
|
||||||
case ATTR_DOMAIN_EDGE:
|
case ATTR_DOMAIN_FACE:
|
||||||
return 2;
|
return 2;
|
||||||
case ATTR_DOMAIN_POINT:
|
case ATTR_DOMAIN_EDGE:
|
||||||
return 3;
|
return 3;
|
||||||
case ATTR_DOMAIN_CORNER:
|
case ATTR_DOMAIN_POINT:
|
||||||
return 4;
|
return 4;
|
||||||
|
case ATTR_DOMAIN_CORNER:
|
||||||
|
return 5;
|
||||||
default:
|
default:
|
||||||
/* Domain not supported in nodes yet. */
|
/* Domain not supported in nodes yet. */
|
||||||
BLI_assert_unreachable();
|
BLI_assert_unreachable();
|
||||||
@@ -1448,6 +1450,7 @@ static StringRef get_random_id_attribute_name(const AttributeDomain domain)
|
|||||||
{
|
{
|
||||||
switch (domain) {
|
switch (domain) {
|
||||||
case ATTR_DOMAIN_POINT:
|
case ATTR_DOMAIN_POINT:
|
||||||
|
case ATTR_DOMAIN_INSTANCE:
|
||||||
return "id";
|
return "id";
|
||||||
default:
|
default:
|
||||||
return "";
|
return "";
|
||||||
|
|||||||
@@ -363,12 +363,22 @@ blender::Span<int> InstancesComponent::almost_unique_ids() const
|
|||||||
|
|
||||||
int InstancesComponent::attribute_domain_size(const AttributeDomain domain) const
|
int InstancesComponent::attribute_domain_size(const AttributeDomain domain) const
|
||||||
{
|
{
|
||||||
if (domain != ATTR_DOMAIN_POINT) {
|
if (domain != ATTR_DOMAIN_INSTANCE) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
return this->instances_amount();
|
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 {
|
namespace blender::bke {
|
||||||
|
|
||||||
static float3 get_transform_position(const float4x4 &transform)
|
static float3 get_transform_position(const float4x4 &transform)
|
||||||
@@ -385,7 +395,7 @@ class InstancePositionAttributeProvider final : public BuiltinAttributeProvider
|
|||||||
public:
|
public:
|
||||||
InstancePositionAttributeProvider()
|
InstancePositionAttributeProvider()
|
||||||
: BuiltinAttributeProvider(
|
: 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:
|
public:
|
||||||
InstanceIDAttributeProvider()
|
InstanceIDAttributeProvider()
|
||||||
: BuiltinAttributeProvider(
|
: 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 InstancePositionAttributeProvider position;
|
||||||
static InstanceIDAttributeProvider id;
|
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
|
} // namespace blender::bke
|
||||||
|
|
||||||
|
|||||||
@@ -72,6 +72,7 @@ const EnumPropertyItem rna_enum_attribute_domain_items[] = {
|
|||||||
/* Not implement yet */
|
/* Not implement yet */
|
||||||
// {ATTR_DOMAIN_GRIDS, "GRIDS", 0, "Grids", "Attribute on mesh multires grids"},
|
// {ATTR_DOMAIN_GRIDS, "GRIDS", 0, "Grids", "Attribute on mesh multires grids"},
|
||||||
{ATTR_DOMAIN_CURVE, "CURVE", 0, "Spline", "Attribute on spline"},
|
{ATTR_DOMAIN_CURVE, "CURVE", 0, "Spline", "Attribute on spline"},
|
||||||
|
{ATTR_DOMAIN_INSTANCE, "INSTANCE", 0, "Instance", "Attribute on instance"},
|
||||||
{0, NULL, 0, NULL, NULL},
|
{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_EDGE, "EDGE", 0, "Edge", "Attribute on mesh edge"},
|
||||||
{ATTR_DOMAIN_FACE, "FACE", 0, "Face", "Attribute on mesh faces"},
|
{ATTR_DOMAIN_FACE, "FACE", 0, "Face", "Attribute on mesh faces"},
|
||||||
{ATTR_DOMAIN_CURVE, "CURVE", 0, "Spline", "Attribute on spline"},
|
{ATTR_DOMAIN_CURVE, "CURVE", 0, "Spline", "Attribute on spline"},
|
||||||
|
{ATTR_DOMAIN_INSTANCE, "INSTANCE", 0, "Instance", "Attribute on instance"},
|
||||||
{0, NULL, 0, NULL, NULL},
|
{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_FACE, "FACE", 0, "Face", "Attribute on mesh faces"},
|
||||||
{ATTR_DOMAIN_CORNER, "CORNER", 0, "Face Corner", "Attribute on mesh face corner"},
|
{ATTR_DOMAIN_CORNER, "CORNER", 0, "Face Corner", "Attribute on mesh face corner"},
|
||||||
{ATTR_DOMAIN_CURVE, "CURVE", 0, "Spline", "Attribute on spline"},
|
{ATTR_DOMAIN_CURVE, "CURVE", 0, "Spline", "Attribute on spline"},
|
||||||
|
{ATTR_DOMAIN_INSTANCE, "INSTANCE", 0, "Instance", "Attribute on instance"},
|
||||||
{0, NULL, 0, NULL, NULL},
|
{0, NULL, 0, NULL, NULL},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -3090,7 +3090,7 @@ static void rna_SpaceSpreadsheet_geometry_component_type_update(Main *UNUSED(bma
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case GEO_COMPONENT_TYPE_INSTANCES: {
|
case GEO_COMPONENT_TYPE_INSTANCES: {
|
||||||
sspreadsheet->attribute_domain = ATTR_DOMAIN_POINT;
|
sspreadsheet->attribute_domain = ATTR_DOMAIN_INSTANCE;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case GEO_COMPONENT_TYPE_VOLUME: {
|
case GEO_COMPONENT_TYPE_VOLUME: {
|
||||||
|
|||||||
@@ -34,8 +34,11 @@ static void set_position_in_component(GeometryComponent &component,
|
|||||||
const Field<float3> &position_field,
|
const Field<float3> &position_field,
|
||||||
const Field<float3> &offset_field)
|
const Field<float3> &offset_field)
|
||||||
{
|
{
|
||||||
GeometryComponentFieldContext field_context{component, ATTR_DOMAIN_POINT};
|
AttributeDomain domain = component.type() == GEO_COMPONENT_TYPE_INSTANCES ?
|
||||||
const int domain_size = component.attribute_domain_size(ATTR_DOMAIN_POINT);
|
ATTR_DOMAIN_INSTANCE :
|
||||||
|
ATTR_DOMAIN_POINT;
|
||||||
|
GeometryComponentFieldContext field_context{component, domain};
|
||||||
|
const int domain_size = component.attribute_domain_size(domain);
|
||||||
if (domain_size == 0) {
|
if (domain_size == 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -57,7 +60,7 @@ static void set_position_in_component(GeometryComponent &component,
|
|||||||
const VArray<float3> &offsets_input = position_evaluator.get_evaluated<float3>(1);
|
const VArray<float3> &offsets_input = position_evaluator.get_evaluated<float3>(1);
|
||||||
|
|
||||||
OutputAttribute_Typed<float3> positions = component.attribute_try_get_for_output<float3>(
|
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();
|
MutableSpan<float3> position_mutable = positions.as_span();
|
||||||
|
|
||||||
for (int i : selection) {
|
for (int i : selection) {
|
||||||
|
|||||||
Reference in New Issue
Block a user