From 0be7678702f079e9e206b4f683d927e2792dea44 Mon Sep 17 00:00:00 2001 From: Jacques Lucke Date: Tue, 14 Oct 2025 16:57:26 +0200 Subject: [PATCH] Fix #148003: crash when using incorrect grid type in Get Named Grid node The node was lacking any grid type checking. Now it also does implicit conversions when the requested grid type does not match the type of the stored grid. Pull Request: https://projects.blender.org/blender/blender/pulls/148038 --- .../geometry/nodes/node_geo_get_named_grid.cc | 69 +++++++++++++++---- 1 file changed, 56 insertions(+), 13 deletions(-) diff --git a/source/blender/nodes/geometry/nodes/node_geo_get_named_grid.cc b/source/blender/nodes/geometry/nodes/node_geo_get_named_grid.cc index 6c0c73ea203..7a630aa7e0a 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_get_named_grid.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_get_named_grid.cc @@ -43,6 +43,45 @@ static void node_layout(uiLayout *layout, bContext * /*C*/, PointerRNA *ptr) layout->prop(ptr, "data_type", UI_ITEM_NONE, "", ICON_NONE); } +#ifdef WITH_OPENVDB +static std::optional try_get_named_grid( + GeoNodeExecParams ¶ms, + Volume &volume, + const StringRef grid_name, + const bool remove_grid, + const eNodeSocketDatatype desired_socket_type) +{ + const bke::VolumeGridData *grid = BKE_volume_grid_find(&volume, grid_name); + if (!grid) { + return std::nullopt; + } + const VolumeGridType stored_grid_type = grid->grid_type(); + const std::optional current_socket_type = bke::grid_type_to_socket_type( + stored_grid_type); + if (!current_socket_type) { + return std::nullopt; + } + /* Increment user count before removing from volume. */ + grid->add_user(); + if (remove_grid) { + BKE_volume_grid_remove(&volume, grid); + } + SocketValueVariant value_variant = SocketValueVariant::From(bke::GVolumeGrid(grid)); + if (current_socket_type != desired_socket_type) { + std::optional converted_value = implicitly_convert_socket_value( + *bke::node_socket_type_find_static(*current_socket_type), + value_variant, + *bke::node_socket_type_find_static(desired_socket_type)); + if (!converted_value) { + return std::nullopt; + } + params.error_message_add(NodeWarningType::Info, "Implicit grid type conversion"); + value_variant = std::move(*converted_value); + } + return value_variant; +} +#endif + static void node_geo_exec(GeoNodeExecParams params) { #ifdef WITH_OPENVDB @@ -50,25 +89,29 @@ static void node_geo_exec(GeoNodeExecParams params) GeometrySet geometry_set = params.extract_input("Volume"); const std::string grid_name = params.extract_input("Name"); const bool remove_grid = params.extract_input("Remove"); - const VolumeGridType grid_type = *bke::socket_type_to_grid_type( - eNodeSocketDatatype(node.custom1)); + const eNodeSocketDatatype socket_type = eNodeSocketDatatype(node.custom1); if (Volume *volume = geometry_set.get_volume_for_write()) { - if (const bke::VolumeGridData *grid = BKE_volume_grid_find(volume, grid_name)) { - /* Increment user count before removing from volume. */ - grid->add_user(); - if (remove_grid) { - BKE_volume_grid_remove(volume, grid); - } - - params.set_output("Grid", bke::GVolumeGrid(grid)); - params.set_output("Volume", geometry_set); + if (std::optional value_variant = try_get_named_grid( + params, *volume, grid_name, remove_grid, socket_type)) + { + params.set_output("Grid", std::move(*value_variant)); + params.set_output("Volume", std::move(geometry_set)); return; } } + if (!grid_name.empty()) { + params.error_message_add(NodeWarningType::Warning, + "No supported grid found with the given name"); + } + if (std::optional grid_type = bke::socket_type_to_grid_type(socket_type)) { + params.set_output("Grid", bke::GVolumeGrid(*grid_type)); + params.set_output("Volume", std::move(geometry_set)); + return; + } + params.set_output("Volume", std::move(geometry_set)); + params.set_default_remaining_outputs(); - params.set_output("Grid", bke::GVolumeGrid(grid_type)); - params.set_output("Volume", geometry_set); #else node_geo_exec_with_missing_openvdb(params); #endif