Changeset View
Changeset View
Standalone View
Standalone View
source/blender/nodes/geometry/nodes/node_geo_transfer_attribute.cc
| Show All 35 Lines | |||||
| using namespace blender::bke::mesh_surface_sample; | using namespace blender::bke::mesh_surface_sample; | ||||
| using blender::fn::GArray; | using blender::fn::GArray; | ||||
| namespace blender::nodes { | namespace blender::nodes { | ||||
| static void geo_node_transfer_attribute_declare(NodeDeclarationBuilder &b) | static void geo_node_transfer_attribute_declare(NodeDeclarationBuilder &b) | ||||
| { | { | ||||
| b.add_input<decl::Geometry>(N_("Target")) | b.add_input<decl::Geometry>(N_("Target")) | ||||
| .only_realized_data() | .supported_type({GEO_COMPONENT_TYPE_MESH, | ||||
| .supported_type( | GEO_COMPONENT_TYPE_POINT_CLOUD, | ||||
| {GEO_COMPONENT_TYPE_MESH, GEO_COMPONENT_TYPE_POINT_CLOUD, GEO_COMPONENT_TYPE_CURVE}); | GEO_COMPONENT_TYPE_CURVE, | ||||
| GEO_COMPONENT_TYPE_INSTANCES}); | |||||
| b.add_input<decl::Vector>(N_("Attribute")).hide_value().supports_field(); | b.add_input<decl::Vector>(N_("Attribute")).hide_value().supports_field(); | ||||
| b.add_input<decl::Float>(N_("Attribute"), "Attribute_001").hide_value().supports_field(); | b.add_input<decl::Float>(N_("Attribute"), "Attribute_001").hide_value().supports_field(); | ||||
| b.add_input<decl::Color>(N_("Attribute"), "Attribute_002").hide_value().supports_field(); | b.add_input<decl::Color>(N_("Attribute"), "Attribute_002").hide_value().supports_field(); | ||||
| b.add_input<decl::Bool>(N_("Attribute"), "Attribute_003").hide_value().supports_field(); | b.add_input<decl::Bool>(N_("Attribute"), "Attribute_003").hide_value().supports_field(); | ||||
| b.add_input<decl::Int>(N_("Attribute"), "Attribute_004").hide_value().supports_field(); | b.add_input<decl::Int>(N_("Attribute"), "Attribute_004").hide_value().supports_field(); | ||||
| b.add_input<decl::Vector>(N_("Source Position")).implicit_field(); | b.add_input<decl::Vector>(N_("Source Position")).implicit_field(); | ||||
| ▲ Show 20 Lines • Show All 533 Lines • ▼ Show 20 Lines | private: | ||||
| } | } | ||||
| }; | }; | ||||
| static const GeometryComponent *find_target_component(const GeometrySet &geometry, | static const GeometryComponent *find_target_component(const GeometrySet &geometry, | ||||
| const AttributeDomain domain) | const AttributeDomain domain) | ||||
| { | { | ||||
| /* Choose the other component based on a consistent order, rather than some more complicated | /* 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. */ | * heuristic. This is the same order visible in the spreadsheet and used in the ray-cast node. */ | ||||
| static const Array<GeometryComponentType> supported_types = { | static const Array<GeometryComponentType> supported_types = {GEO_COMPONENT_TYPE_MESH, | ||||
| GEO_COMPONENT_TYPE_MESH, GEO_COMPONENT_TYPE_POINT_CLOUD, GEO_COMPONENT_TYPE_CURVE}; | GEO_COMPONENT_TYPE_POINT_CLOUD, | ||||
| GEO_COMPONENT_TYPE_CURVE, | |||||
| GEO_COMPONENT_TYPE_INSTANCES}; | |||||
| for (const GeometryComponentType src_type : supported_types) { | for (const GeometryComponentType src_type : supported_types) { | ||||
| if (component_is_available(geometry, src_type, domain)) { | if (component_is_available(geometry, src_type, domain)) { | ||||
| return geometry.get_component_for_read(src_type); | return geometry.get_component_for_read(src_type); | ||||
| } | } | ||||
| } | } | ||||
| return nullptr; | return nullptr; | ||||
| } | } | ||||
| ▲ Show 20 Lines • Show All 126 Lines • ▼ Show 20 Lines | static void geo_node_transfer_attribute_exec(GeoNodeExecParams params) | ||||
| auto return_default = [&]() { | auto return_default = [&]() { | ||||
| attribute_math::convert_to_static_type(data_type, [&](auto dummy) { | attribute_math::convert_to_static_type(data_type, [&](auto dummy) { | ||||
| using T = decltype(dummy); | using T = decltype(dummy); | ||||
| output_attribute_field(params, fn::make_constant_field<T>(T())); | output_attribute_field(params, fn::make_constant_field<T>(T())); | ||||
| }); | }); | ||||
| }; | }; | ||||
| /* 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; | GField output_field; | ||||
| switch (mapping) { | switch (mapping) { | ||||
| case GEO_NODE_ATTRIBUTE_TRANSFER_NEAREST_FACE_INTERPOLATED: { | case GEO_NODE_ATTRIBUTE_TRANSFER_NEAREST_FACE_INTERPOLATED: { | ||||
| const Mesh *mesh = geometry.get_mesh_for_read(); | const Mesh *mesh = geometry.get_mesh_for_read(); | ||||
| if (mesh == nullptr) { | if (mesh == nullptr) { | ||||
| if (!geometry.is_empty()) { | if (!geometry.is_empty()) { | ||||
| params.error_message_add(NodeWarningType::Error, | params.error_message_add(NodeWarningType::Error, | ||||
| TIP_("The target geometry must contain a mesh")); | TIP_("The target geometry must contain a mesh")); | ||||
| ▲ Show 20 Lines • Show All 64 Lines • Show Last 20 Lines | |||||