diff --git a/source/blender/nodes/NOD_geometry_nodes_values.hh b/source/blender/nodes/NOD_geometry_nodes_values.hh index 4e80f736cb9..7070c734cef 100644 --- a/source/blender/nodes/NOD_geometry_nodes_values.hh +++ b/source/blender/nodes/NOD_geometry_nodes_values.hh @@ -46,11 +46,34 @@ template constexpr bool is_GeoNodesMultiInput_v &owned_fn, + Span input_values, + Span output_values, + GeoNodesUserData *user_data, + std::string &r_error_message); + +[[nodiscard]] inline bool execute_multi_function_on_value_variant( const std::shared_ptr &owned_fn, const Span input_values, const Span output_values, GeoNodesUserData *user_data, - std::string &r_error_message); + std::string &r_error_message) +{ + const mf::MultiFunction &fn = *owned_fn; + return execute_multi_function_on_value_variant( + fn, std::move(owned_fn), input_values, output_values, user_data, r_error_message); +} + +[[nodiscard]] inline bool execute_multi_function_on_value_variant( + const mf::MultiFunction &fn, + const Span input_values, + const Span output_values, + GeoNodesUserData *user_data, + std::string &r_error_message) +{ + return execute_multi_function_on_value_variant( + fn, {}, input_values, output_values, user_data, r_error_message); +} /** * Performs implicit conversion between socket types. Returns false if the conversion is not diff --git a/source/blender/nodes/geometry/nodes/node_geo_curve_sample.cc b/source/blender/nodes/geometry/nodes/node_geo_curve_sample.cc index b6814b154de..2c8874ac713 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_curve_sample.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_curve_sample.cc @@ -39,6 +39,7 @@ static void node_declare(NodeDeclarationBuilder &b) .max(1.0f) .subtype(PROP_FACTOR) .supports_field() + .structure_type(StructureType::Dynamic) .make_available([](bNode &node) { node_storage(node).mode = GEO_NODE_CURVE_SAMPLE_FACTOR; }); @@ -46,13 +47,15 @@ static void node_declare(NodeDeclarationBuilder &b) .min(0.0f) .subtype(PROP_DISTANCE) .supports_field() + .structure_type(StructureType::Dynamic) .make_available([](bNode &node) { node_storage(node).mode = GEO_NODE_CURVE_SAMPLE_LENGTH; }); - auto &index = - b.add_input("Curve Index").supports_field().make_available([](bNode &node) { - node_storage(node).use_all_curves = false; - }); + auto &index = b.add_input("Curve Index") + .supports_field() + .structure_type(StructureType::Dynamic) + .make_available( + [](bNode &node) { node_storage(node).use_all_curves = false; }); if (const bNode *node = b.node_or_null()) { const NodeGeometryCurveSample &storage = node_storage(*node); @@ -480,43 +483,83 @@ static void node_geo_exec(GeoNodeExecParams params) const NodeGeometryCurveSample &storage = node_storage(params.node()); const GeometryNodeCurveSampleMode mode = GeometryNodeCurveSampleMode(storage.mode); - Field length_field = params.extract_input>( - mode == GEO_NODE_CURVE_SAMPLE_FACTOR ? "Factor" : "Length"); + const StringRef length_input_name = mode == GEO_NODE_CURVE_SAMPLE_FACTOR ? "Factor" : "Length"; + auto sample_length = params.extract_input(length_input_name); + GField src_values_field = params.extract_input("Value"); + std::string error_message; + + bke::SocketValueVariant position; + bke::SocketValueVariant tangent; + bke::SocketValueVariant normal; + bke::SocketValueVariant value; std::shared_ptr sample_op; if (curves.curves_num() == 1) { - sample_op = FieldOperation::from( - std::make_unique( - std::move(geometry_set), mode, std::move(src_values_field)), - {fn::make_constant_field(0), std::move(length_field)}); + auto curve_index = bke::SocketValueVariant::From(fn::make_constant_field(0)); + if (!execute_multi_function_on_value_variant( + std::make_unique( + std::move(geometry_set), mode, std::move(src_values_field)), + {&curve_index, &sample_length}, + {&position, &tangent, &normal, &value}, + params.user_data(), + error_message)) + { + params.set_default_remaining_outputs(); + params.error_message_add(NodeWarningType::Error, std::move(error_message)); + return; + } } else { if (storage.use_all_curves) { - auto index_fn = std::make_unique( - curve_accumulated_lengths(curves), mode); - auto index_op = FieldOperation::from(std::move(index_fn), {std::move(length_field)}); - Field curve_index = Field(index_op, 0); - Field length_in_curve = Field(index_op, 1); - sample_op = FieldOperation::from( - std::make_unique( - std::move(geometry_set), GEO_NODE_CURVE_SAMPLE_LENGTH, std::move(src_values_field)), - {std::move(curve_index), std::move(length_in_curve)}); + bke::SocketValueVariant curve_index; + bke::SocketValueVariant length_in_curve; + if (!execute_multi_function_on_value_variant(std::make_unique( + curve_accumulated_lengths(curves), mode), + {&sample_length}, + {&curve_index, &length_in_curve}, + params.user_data(), + error_message)) + { + params.set_default_remaining_outputs(); + params.error_message_add(NodeWarningType::Error, std::move(error_message)); + return; + } + if (!execute_multi_function_on_value_variant( + std::make_shared(std::move(geometry_set), + GEO_NODE_CURVE_SAMPLE_LENGTH, + std::move(src_values_field)), + {&curve_index, &length_in_curve}, + {&position, &tangent, &normal, &value}, + params.user_data(), + error_message)) + { + params.set_default_remaining_outputs(); + params.error_message_add(NodeWarningType::Error, std::move(error_message)); + return; + } } else { - Field curve_index = params.extract_input>("Curve Index"); - Field length_in_curve = std::move(length_field); - sample_op = FieldOperation::from( - std::make_unique( - std::move(geometry_set), mode, std::move(src_values_field)), - {std::move(curve_index), std::move(length_in_curve)}); + auto curve_index = params.extract_input("Curve Index"); + if (!execute_multi_function_on_value_variant( + std::make_shared( + std::move(geometry_set), mode, std::move(src_values_field)), + {&curve_index, &sample_length}, + {&position, &tangent, &normal, &value}, + params.user_data(), + error_message)) + { + params.set_default_remaining_outputs(); + params.error_message_add(NodeWarningType::Error, std::move(error_message)); + return; + } } } - params.set_output("Position", Field(sample_op, 0)); - params.set_output("Tangent", Field(sample_op, 1)); - params.set_output("Normal", Field(sample_op, 2)); - params.set_output("Value", GField(sample_op, 3)); + params.set_output("Position", std::move(position)); + params.set_output("Tangent", std::move(tangent)); + params.set_output("Normal", std::move(normal)); + params.set_output("Value", std::move(value)); } static void node_register() diff --git a/source/blender/nodes/geometry/nodes/node_geo_image_texture.cc b/source/blender/nodes/geometry/nodes/node_geo_image_texture.cc index d9ca8267d95..db0630ac262 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_image_texture.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_image_texture.cc @@ -407,12 +407,21 @@ static void node_geo_exec(GeoNodeExecParams params) return; } - Field vector_field = params.extract_input>("Vector"); + auto sample_uv = params.extract_input("Vector"); - auto image_op = FieldOperation::from(std::move(image_fn), {std::move(vector_field)}); + std::string error_message; + bke::SocketValueVariant color; + bke::SocketValueVariant alpha; + if (!execute_multi_function_on_value_variant( + std::move(image_fn), {&sample_uv}, {&color, &alpha}, params.user_data(), error_message)) + { + params.set_default_remaining_outputs(); + params.error_message_add(NodeWarningType::Error, std::move(error_message)); + return; + } - params.set_output("Color", Field(image_op, 0)); - params.set_output("Alpha", Field(image_op, 1)); + params.set_output("Color", std::move(color)); + params.set_output("Alpha", std::move(alpha)); } static void node_register() diff --git a/source/blender/nodes/geometry/nodes/node_geo_list_get_item.cc b/source/blender/nodes/geometry/nodes/node_geo_list_get_item.cc index 749950daf64..44d5dfbc450 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_list_get_item.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_list_get_item.cc @@ -124,14 +124,15 @@ static void node_geo_exec(GeoNodeExecParams params) return; } - auto fn_ptr = std::make_shared(std::move(list)); - const mf::MultiFunction &fn = *fn_ptr; - - bke::SocketValueVariant output_value; std::string error_message; - const bool success = execute_multi_function_on_value_variant( - fn, std::move(fn_ptr), {&index}, {&output_value}, params.user_data(), error_message); - if (!success) { + bke::SocketValueVariant output_value; + if (!execute_multi_function_on_value_variant( + std::make_shared(std::move(list)), + {&index}, + {&output_value}, + params.user_data(), + error_message)) + { params.set_default_remaining_outputs(); params.error_message_add(NodeWarningType::Error, std::move(error_message)); return; diff --git a/source/blender/nodes/geometry/nodes/node_geo_proximity.cc b/source/blender/nodes/geometry/nodes/node_geo_proximity.cc index 1647a088ffe..385817346b0 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_proximity.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_proximity.cc @@ -270,18 +270,32 @@ static void node_geo_exec(GeoNodeExecParams params) } const NodeGeometryProximity &storage = node_storage(params.node()); + const auto target_type = GeometryNodeProximityTargetType(storage.target_element); + Field group_id_field = params.extract_input>("Group ID"); - Field position_field = params.extract_input>("Source Position"); - Field sample_id_field = params.extract_input>("Sample Group ID"); + auto sample_position = params.extract_input("Source Position"); + auto sample_group_id = params.extract_input("Sample Group ID"); - auto proximity_fn = std::make_unique( - std::move(target), GeometryNodeProximityTargetType(storage.target_element), group_id_field); - auto proximity_op = FieldOperation::from( - std::move(proximity_fn), {std::move(position_field), std::move(sample_id_field)}); + std::string error_message; + bke::SocketValueVariant position; + bke::SocketValueVariant distance; + bke::SocketValueVariant is_valid; + if (!execute_multi_function_on_value_variant( + std::make_shared( + std::move(target), target_type, std::move(group_id_field)), + {&sample_position, &sample_group_id}, + {&position, &distance, &is_valid}, + params.user_data(), + error_message)) + { + params.set_default_remaining_outputs(); + params.error_message_add(NodeWarningType::Error, std::move(error_message)); + return; + } - params.set_output("Position", Field(proximity_op, 0)); - params.set_output("Distance", Field(proximity_op, 1)); - params.set_output("Is Valid", Field(proximity_op, 2)); + params.set_output("Position", std::move(position)); + params.set_output("Distance", std::move(distance)); + params.set_output("Is Valid", std::move(is_valid)); } static void node_rna(StructRNA *srna) diff --git a/source/blender/nodes/geometry/nodes/node_geo_raycast.cc b/source/blender/nodes/geometry/nodes/node_geo_raycast.cc index fb33346cb2b..07c214f8051 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_raycast.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_raycast.cc @@ -244,48 +244,105 @@ static void node_geo_exec(GeoNodeExecParams params) return; } - static auto normalize_fn = mf::build::SI1_SO( - "Normalize", - [](const float3 &v) { return math::normalize(v); }, - mf::build::exec_presets::AllSpanOrSingle()); - auto direction_op = FieldOperation::from(normalize_fn, - {params.extract_input>("Ray Direction")}); + std::string error_message; - auto op = FieldOperation::from(std::make_unique(target), - {params.extract_input>("Source Position"), - Field(direction_op), - params.extract_input>("Ray Length")}); + bke::SocketValueVariant normalized_direction; + { + auto ray_direction = params.extract_input("Ray Direction"); - Field hit_position(op, 1); - params.set_output("Is Hit", Field(op, 0)); + static auto normalize_fn = mf::build::SI1_SO( + "Normalize", + [](const float3 &v) { return math::normalize(v); }, + mf::build::exec_presets::AllSpanOrSingle()); + + if (!execute_multi_function_on_value_variant(normalize_fn, + {&ray_direction}, + {&normalized_direction}, + params.user_data(), + error_message)) + { + params.set_default_remaining_outputs(); + params.error_message_add(NodeWarningType::Error, std::move(error_message)); + return; + } + } + + auto position = params.extract_input("Source Position"); + auto ray_length = params.extract_input("Ray Length"); + + bke::SocketValueVariant is_hit; + bke::SocketValueVariant hit_position; + bke::SocketValueVariant hit_normal; + bke::SocketValueVariant hit_distance; + bke::SocketValueVariant triangle_index; + if (!execute_multi_function_on_value_variant( + std::make_unique(target), + {&position, &normalized_direction, &ray_length}, + {&is_hit, &hit_position, &hit_normal, &hit_distance, &triangle_index}, + params.user_data(), + error_message)) + { + params.set_default_remaining_outputs(); + params.error_message_add(NodeWarningType::Error, std::move(error_message)); + return; + } + + params.set_output("Is Hit", std::move(is_hit)); params.set_output("Hit Position", hit_position); - params.set_output("Hit Normal", Field(op, 2)); - params.set_output("Hit Distance", Field(op, 3)); + params.set_output("Hit Normal", std::move(hit_normal)); + params.set_output("Hit Distance", std::move(hit_distance)); if (!params.output_is_required("Attribute")) { return; } GField field = params.extract_input("Attribute"); - Field triangle_index(op, 4); - Field bary_weights; + bke::SocketValueVariant bary_weights; + bke::SocketValueVariant triangle_index_copy = triangle_index; switch (mapping) { case GEO_NODE_RAYCAST_INTERPOLATED: - bary_weights = Field(FieldOperation::from( - std::make_shared(target), - {hit_position, triangle_index})); + if (!execute_multi_function_on_value_variant( + std::make_shared(target), + {&hit_position, &triangle_index_copy}, + {&bary_weights}, + params.user_data(), + error_message)) + { + params.set_default_remaining_outputs(); + params.error_message_add(NodeWarningType::Error, std::move(error_message)); + return; + } break; case GEO_NODE_RAYCAST_NEAREST: - bary_weights = Field(FieldOperation::from( - std::make_shared(target), - {hit_position, triangle_index})); + if (!execute_multi_function_on_value_variant( + std::make_shared(target), + {&hit_position, &triangle_index_copy}, + {&bary_weights}, + params.user_data(), + error_message)) + { + params.set_default_remaining_outputs(); + params.error_message_add(NodeWarningType::Error, std::move(error_message)); + return; + } break; } - auto sample_op = FieldOperation::from( - std::make_shared(std::move(target), - std::move(field)), - {triangle_index, bary_weights}); - params.set_output("Attribute", GField(sample_op)); + + bke::SocketValueVariant sampled_atribute; + if (!execute_multi_function_on_value_variant( + std::make_shared(std::move(target), + std::move(field)), + {&triangle_index, &bary_weights}, + {&sampled_atribute}, + params.user_data(), + error_message)) + { + params.set_default_remaining_outputs(); + params.error_message_add(NodeWarningType::Error, std::move(error_message)); + return; + } + + params.set_output("Attribute", std::move(sampled_atribute)); } static void node_rna(StructRNA *srna) diff --git a/source/blender/nodes/geometry/nodes/node_geo_sample_grid.cc b/source/blender/nodes/geometry/nodes/node_geo_sample_grid.cc index 4bb5a944fb2..cce5e2b4b9c 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_sample_grid.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_sample_grid.cc @@ -227,24 +227,30 @@ class SampleGridFunction : public mf::MultiFunction { static void node_geo_exec(GeoNodeExecParams params) { #ifdef WITH_OPENVDB - const bNode &node = params.node(); - const eNodeSocketDatatype data_type = eNodeSocketDatatype(node.custom1); - const auto interpolation = params.get_input("Interpolation"); - bke::GVolumeGrid grid = params.extract_input("Grid"); if (!grid) { params.set_default_remaining_outputs(); return; } - auto fn = std::make_shared(std::move(grid), interpolation); - auto op = FieldOperation::from(std::move(fn), {params.extract_input>("Position")}); + const auto interpolation = params.get_input("Interpolation"); + bke::SocketValueVariant position = params.extract_input("Position"); - const bke::DataTypeConversions &conversions = bke::get_implicit_type_conversions(); - const CPPType &output_type = *bke::socket_type_to_geo_nodes_base_cpp_type(data_type); - const GField output_field = conversions.try_convert(fn::GField(std::move(op)), output_type); - params.set_output("Value", std::move(output_field)); + std::string error_message; + bke::SocketValueVariant output_value; + if (!execute_multi_function_on_value_variant( + std::make_shared(std::move(grid), interpolation), + {&position}, + {&output_value}, + params.user_data(), + error_message)) + { + params.set_default_remaining_outputs(); + params.error_message_add(NodeWarningType::Error, std::move(error_message)); + return; + } + params.set_output("Value", std::move(output_value)); #else node_geo_exec_with_missing_openvdb(params); #endif diff --git a/source/blender/nodes/geometry/nodes/node_geo_sample_grid_index.cc b/source/blender/nodes/geometry/nodes/node_geo_sample_grid_index.cc index 98989c5679c..2dee8a7026a 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_sample_grid_index.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_sample_grid_index.cc @@ -194,26 +194,31 @@ class SampleGridIndexFunction : public mf::MultiFunction { static void node_geo_exec(GeoNodeExecParams params) { #ifdef WITH_OPENVDB - const bNode &node = params.node(); - const eNodeSocketDatatype data_type = eNodeSocketDatatype(node.custom1); - bke::GVolumeGrid grid = params.extract_input("Grid"); if (!grid) { params.set_default_remaining_outputs(); return; } - auto fn = std::make_shared(std::move(grid)); - auto op = FieldOperation::from(std::move(fn), - {params.extract_input>("X"), - params.extract_input>("Y"), - params.extract_input>("Z")}); + auto x = params.extract_input("X"); + auto y = params.extract_input("Y"); + auto z = params.extract_input("Z"); - const bke::DataTypeConversions &conversions = bke::get_implicit_type_conversions(); - const CPPType &output_type = *bke::socket_type_to_geo_nodes_base_cpp_type(data_type); - const GField output_field = conversions.try_convert(fn::GField(std::move(op)), output_type); - params.set_output("Value", std::move(output_field)); + std::string error_message; + bke::SocketValueVariant output_value; + if (!execute_multi_function_on_value_variant( + std::make_shared(std::move(grid)), + {&x, &y, &z}, + {&output_value}, + params.user_data(), + error_message)) + { + params.set_default_remaining_outputs(); + params.error_message_add(NodeWarningType::Error, std::move(error_message)); + return; + } + params.set_output("Value", std::move(output_value)); #else node_geo_exec_with_missing_openvdb(params); #endif diff --git a/source/blender/nodes/geometry/nodes/node_geo_sample_index.cc b/source/blender/nodes/geometry/nodes/node_geo_sample_index.cc index 6d08084a0f0..574e25f728f 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_sample_index.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_sample_index.cc @@ -206,14 +206,12 @@ static void node_geo_exec(GeoNodeExecParams params) SocketValueVariant index_value_variant = params.extract_input("Index"); const CPPType &cpp_type = value_field.cpp_type(); - if (index_value_variant.is_context_dependent_field()) { - /* If the index is a field, the output has to be a field that still depends on the input. */ - auto fn = std::make_shared( - std::move(geometry), std::move(value_field), domain, use_clamp); - auto op = FieldOperation::from(std::move(fn), {index_value_variant.extract>()}); - params.set_output("Value", GField(std::move(op))); - } - else if (const GeometryComponent *component = find_source_component(geometry, domain)) { + if (index_value_variant.is_single()) { + const GeometryComponent *component = find_source_component(geometry, domain); + if (!component) { + params.set_default_remaining_outputs(); + return; + } /* Optimization for the case when the index is a single value. Here only that one index has to * be evaluated. */ const int domain_size = component->attribute_domain_size(domain); @@ -236,11 +234,25 @@ static void node_geo_exec(GeoNodeExecParams params) else { params.set_output("Value", fn::make_constant_field(cpp_type, cpp_type.default_value())); } + return; } - else { - /* Output default value if there is no geometry. */ - params.set_output("Value", fn::make_constant_field(cpp_type, cpp_type.default_value())); + + bke::SocketValueVariant output_value; + std::string error_message; + if (!execute_multi_function_on_value_variant( + std::make_shared( + std::move(geometry), std::move(value_field), domain, use_clamp), + {&index_value_variant}, + {&output_value}, + params.user_data(), + error_message)) + { + params.set_default_remaining_outputs(); + params.error_message_add(NodeWarningType::Error, std::move(error_message)); + return; } + + params.set_output("Value", std::move(output_value)); } static void node_register() diff --git a/source/blender/nodes/geometry/nodes/node_geo_sample_nearest.cc b/source/blender/nodes/geometry/nodes/node_geo_sample_nearest.cc index 92bfd305f7c..995127ff73d 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_sample_nearest.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_sample_nearest.cc @@ -311,10 +311,23 @@ static void node_geo_exec(GeoNodeExecParams params) return; } - Field positions = params.extract_input>("Sample Position"); - auto fn = std::make_shared(std::move(geometry), domain); - auto op = FieldOperation::from(std::move(fn), {std::move(positions)}); - params.set_output>("Index", Field(std::move(op))); + auto sample_position = params.extract_input("Sample Position"); + + std::string error_message; + bke::SocketValueVariant index; + if (!execute_multi_function_on_value_variant( + std::make_shared(std::move(geometry), domain), + {&sample_position}, + {&index}, + params.user_data(), + error_message)) + { + params.set_default_remaining_outputs(); + params.error_message_add(NodeWarningType::Error, std::move(error_message)); + return; + } + + params.set_output("Index", std::move(index)); } static void node_rna(StructRNA *srna) diff --git a/source/blender/nodes/geometry/nodes/node_geo_sample_nearest_surface.cc b/source/blender/nodes/geometry/nodes/node_geo_sample_nearest_surface.cc index 8ef93349ba7..5d6b623478b 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_sample_nearest_surface.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_sample_nearest_surface.cc @@ -203,26 +203,58 @@ static void node_geo_exec(GeoNodeExecParams params) return; } - auto nearest_op = FieldOperation::from( - std::make_shared(geometry, - params.extract_input>("Group ID")), - {params.extract_input>("Sample Position"), - params.extract_input>("Sample Group ID")}); - Field triangle_indices(nearest_op, 0); - Field nearest_positions(nearest_op, 1); - Field is_valid(nearest_op, 2); + GField value = params.extract_input("Value"); + Field group_id_field = params.extract_input>("Group ID"); + auto sample_position = params.extract_input("Sample Position"); + auto sample_group_id = params.extract_input("Sample Group ID"); - Field bary_weights = Field(FieldOperation::from( - std::make_shared(geometry), - {nearest_positions, triangle_indices})); + std::string error_message; - GField field = params.extract_input("Value"); - auto sample_op = FieldOperation::from( - std::make_shared(geometry, std::move(field)), - {triangle_indices, bary_weights}); + bke::SocketValueVariant triangle_index; + bke::SocketValueVariant nearest_positions; + bke::SocketValueVariant is_valid; + if (!execute_multi_function_on_value_variant( + std::make_shared(geometry, group_id_field), + {&sample_position, &sample_group_id}, + {&triangle_index, &nearest_positions, &is_valid}, + params.user_data(), + error_message)) + { + params.set_default_remaining_outputs(); + params.error_message_add(NodeWarningType::Error, std::move(error_message)); + return; + } - params.set_output("Value", GField(sample_op)); - params.set_output("Is Valid", is_valid); + bke::SocketValueVariant bary_weights; + bke::SocketValueVariant triangle_index_copy = triangle_index; + if (!execute_multi_function_on_value_variant( + std::make_shared(geometry), + {&nearest_positions, &triangle_index_copy}, + {&bary_weights}, + params.user_data(), + error_message)) + { + params.set_default_remaining_outputs(); + params.error_message_add(NodeWarningType::Error, std::move(error_message)); + return; + } + + bke::SocketValueVariant sample_value; + if (!execute_multi_function_on_value_variant( + std::make_shared(geometry, + std::move(value)), + {&triangle_index, &bary_weights}, + {&sample_value}, + params.user_data(), + error_message)) + { + params.set_default_remaining_outputs(); + params.error_message_add(NodeWarningType::Error, std::move(error_message)); + return; + } + + params.set_output("Value", std::move(sample_value)); + params.set_output("Is Valid", std::move(is_valid)); } static void node_rna(StructRNA *srna) diff --git a/source/blender/nodes/geometry/nodes/node_geo_sample_uv_surface.cc b/source/blender/nodes/geometry/nodes/node_geo_sample_uv_surface.cc index 545f768f9e0..5f516440802 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_sample_uv_surface.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_sample_uv_surface.cc @@ -166,8 +166,19 @@ static void node_geo_exec(GeoNodeExecParams params) const CPPType &float2_type = CPPType::get(); Field source_uv_map = conversions.try_convert( params.extract_input>("Source UV Map"), float2_type); - Field sample_uvs = conversions.try_convert( - params.extract_input>("Sample UV"), float2_type); + + auto sample_uv_value = params.extract_input("Sample UV"); + if (sample_uv_value.is_list()) { + params.error_message_add(NodeWarningType::Error, + "Lists are not supported for \"Sample UV\" input"); + } + if (sample_uv_value.is_volume_grid()) { + params.error_message_add(NodeWarningType::Error, + "Volume grids are not supported for \"Sample UV\" input"); + } + Field sample_uvs = conversions.try_convert(sample_uv_value.extract>(), + float2_type); + auto uv_op = FieldOperation::from( std::make_shared(geometry, std::move(source_uv_map)), {std::move(sample_uvs)}); diff --git a/source/blender/nodes/intern/geometry_nodes_lazy_function.cc b/source/blender/nodes/intern/geometry_nodes_lazy_function.cc index 01c3e8ee0d9..c5674be15ae 100644 --- a/source/blender/nodes/intern/geometry_nodes_lazy_function.cc +++ b/source/blender/nodes/intern/geometry_nodes_lazy_function.cc @@ -557,7 +557,7 @@ std::optional implicitly_convert_socket_value( SocketValueVariant output_variant; std::string error_message; if (!execute_multi_function_on_value_variant( - multi_fn, {}, {&input_variant}, {&output_variant}, nullptr, error_message)) + multi_fn, {&input_variant}, {&output_variant}, nullptr, error_message)) { return std::nullopt; } @@ -588,7 +588,7 @@ class LazyFunctionForImplicitConversion : public LazyFunction { BLI_assert(to_value != nullptr); std::string error_message; if (!execute_multi_function_on_value_variant( - fn_, {}, {from_value}, {to_value}, nullptr, error_message)) + fn_, {from_value}, {to_value}, nullptr, error_message)) { std::destroy_at(to_value); construct_socket_default_value(dst_type_, to_value);