From 15ecd47b9685dffdf5973bf184a90b485a12160e Mon Sep 17 00:00:00 2001 From: Erik Date: Fri, 19 Nov 2021 23:36:47 +0100 Subject: 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 --- .../geometry/nodes/node_geo_attribute_capture.cc | 29 +++++++++++++++------- .../geometry/nodes/node_geo_transfer_attribute.cc | 17 ++++++------- 2 files changed, 28 insertions(+), 18 deletions(-) (limited to 'source/blender/nodes/geometry') diff --git a/source/blender/nodes/geometry/nodes/node_geo_attribute_capture.cc b/source/blender/nodes/geometry/nodes/node_geo_attribute_capture.cc index 19deb761948..1cb26646d5a 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_attribute_capture.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_attribute_capture.cc @@ -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 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 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( std::move(anonymous_id), type, params.attribute_producer_name())}; diff --git a/source/blender/nodes/geometry/nodes/node_geo_transfer_attribute.cc b/source/blender/nodes/geometry/nodes/node_geo_transfer_attribute.cc index 3b30806d8ae..74b4c5d30c0 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_transfer_attribute.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_transfer_attribute.cc @@ -41,9 +41,10 @@ namespace blender::nodes { static void geo_node_transfer_attribute_declare(NodeDeclarationBuilder &b) { b.add_input(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(N_("Attribute")).hide_value().supports_field(); b.add_input(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 supported_types = { - GEO_COMPONENT_TYPE_MESH, GEO_COMPONENT_TYPE_POINT_CLOUD, GEO_COMPONENT_TYPE_CURVE}; + static const Array 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: { -- cgit v1.2.3