Geometry Nodes: Instance attributes in Transfer/Capture nodes

Updates the Transfer Attributes and Capture Attributes nodes
to support attributes from instances.

Differential Revision: https://developer.blender.org/D13292
This commit is contained in:
Erik Abrahamsson 2021-11-19 23:36:47 +01:00
parent 01df48a983
commit 15ecd47b96
Notes: blender-bot 2023-02-14 07:31:34 +01:00
Referenced by issue #93367, Geometry Nodes in recent builds scramble meshes in various cases
Referenced by issue #93256, Geometry Nodes: Instances to points doesn't generate any points
2 changed files with 28 additions and 18 deletions

View File

@ -147,16 +147,27 @@ static void geo_node_attribute_capture_exec(GeoNodeExecParams params)
WeakAnonymousAttributeID anonymous_id{"Attribute"};
const CPPType &type = field.cpp_type();
static const Array<GeometryComponentType> types = {
GEO_COMPONENT_TYPE_MESH, GEO_COMPONENT_TYPE_POINT_CLOUD, GEO_COMPONENT_TYPE_CURVE};
geometry_set.modify_geometry_sets([&](GeometrySet &geometry_set) {
for (const GeometryComponentType type : types) {
if (geometry_set.has(type)) {
GeometryComponent &component = geometry_set.get_component_for_write(type);
try_capture_field_on_geometry(component, anonymous_id.get(), domain, field);
}
/* Run on the instances component separately to only affect the top level of instances. */
if (domain == ATTR_DOMAIN_INSTANCE) {
if (geometry_set.has_instances()) {
GeometryComponent &component = geometry_set.get_component_for_write(
GEO_COMPONENT_TYPE_INSTANCES);
try_capture_field_on_geometry(component, anonymous_id.get(), domain, field);
}
});
}
else {
static const Array<GeometryComponentType> types = {
GEO_COMPONENT_TYPE_MESH, GEO_COMPONENT_TYPE_POINT_CLOUD, GEO_COMPONENT_TYPE_CURVE};
geometry_set.modify_geometry_sets([&](GeometrySet &geometry_set) {
for (const GeometryComponentType type : types) {
if (geometry_set.has(type)) {
GeometryComponent &component = geometry_set.get_component_for_write(type);
try_capture_field_on_geometry(component, anonymous_id.get(), domain, field);
}
}
});
}
GField output_field{std::make_shared<bke::AnonymousAttributeFieldInput>(
std::move(anonymous_id), type, params.attribute_producer_name())};

View File

@ -41,9 +41,10 @@ namespace blender::nodes {
static void geo_node_transfer_attribute_declare(NodeDeclarationBuilder &b)
{
b.add_input<decl::Geometry>(N_("Target"))
.only_realized_data()
.supported_type(
{GEO_COMPONENT_TYPE_MESH, GEO_COMPONENT_TYPE_POINT_CLOUD, GEO_COMPONENT_TYPE_CURVE});
.supported_type({GEO_COMPONENT_TYPE_MESH,
GEO_COMPONENT_TYPE_POINT_CLOUD,
GEO_COMPONENT_TYPE_CURVE,
GEO_COMPONENT_TYPE_INSTANCES});
b.add_input<decl::Vector>(N_("Attribute")).hide_value().supports_field();
b.add_input<decl::Float>(N_("Attribute"), "Attribute_001").hide_value().supports_field();
@ -593,8 +594,10 @@ static const GeometryComponent *find_target_component(const GeometrySet &geometr
{
/* Choose the other component based on a consistent order, rather than some more complicated
* heuristic. This is the same order visible in the spreadsheet and used in the ray-cast node. */
static const Array<GeometryComponentType> supported_types = {
GEO_COMPONENT_TYPE_MESH, GEO_COMPONENT_TYPE_POINT_CLOUD, GEO_COMPONENT_TYPE_CURVE};
static const Array<GeometryComponentType> supported_types = {GEO_COMPONENT_TYPE_MESH,
GEO_COMPONENT_TYPE_POINT_CLOUD,
GEO_COMPONENT_TYPE_CURVE,
GEO_COMPONENT_TYPE_INSTANCES};
for (const GeometryComponentType src_type : supported_types) {
if (component_is_available(geometry, src_type, domain)) {
return geometry.get_component_for_read(src_type);
@ -737,10 +740,6 @@ static void geo_node_transfer_attribute_exec(GeoNodeExecParams params)
});
};
/* Since the instances are not used, there is no point in keeping
* a reference to them while the field is passed around. */
geometry.remove(GEO_COMPONENT_TYPE_INSTANCES);
GField output_field;
switch (mapping) {
case GEO_NODE_ATTRIBUTE_TRANSFER_NEAREST_FACE_INTERPOLATED: {