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
This commit is contained in:
Jacques Lucke
2025-10-14 16:57:26 +02:00
parent db6bb01938
commit 0be7678702

View File

@@ -43,6 +43,45 @@ static void node_layout(uiLayout *layout, bContext * /*C*/, PointerRNA *ptr)
layout->prop(ptr, "data_type", UI_ITEM_NONE, "", ICON_NONE); layout->prop(ptr, "data_type", UI_ITEM_NONE, "", ICON_NONE);
} }
#ifdef WITH_OPENVDB
static std::optional<SocketValueVariant> try_get_named_grid(
GeoNodeExecParams &params,
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<eNodeSocketDatatype> 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<SocketValueVariant> 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) static void node_geo_exec(GeoNodeExecParams params)
{ {
#ifdef WITH_OPENVDB #ifdef WITH_OPENVDB
@@ -50,25 +89,29 @@ static void node_geo_exec(GeoNodeExecParams params)
GeometrySet geometry_set = params.extract_input<GeometrySet>("Volume"); GeometrySet geometry_set = params.extract_input<GeometrySet>("Volume");
const std::string grid_name = params.extract_input<std::string>("Name"); const std::string grid_name = params.extract_input<std::string>("Name");
const bool remove_grid = params.extract_input<bool>("Remove"); const bool remove_grid = params.extract_input<bool>("Remove");
const VolumeGridType grid_type = *bke::socket_type_to_grid_type( const eNodeSocketDatatype socket_type = eNodeSocketDatatype(node.custom1);
eNodeSocketDatatype(node.custom1));
if (Volume *volume = geometry_set.get_volume_for_write()) { if (Volume *volume = geometry_set.get_volume_for_write()) {
if (const bke::VolumeGridData *grid = BKE_volume_grid_find(volume, grid_name)) { if (std::optional<SocketValueVariant> value_variant = try_get_named_grid(
/* Increment user count before removing from volume. */ params, *volume, grid_name, remove_grid, socket_type))
grid->add_user(); {
if (remove_grid) { params.set_output("Grid", std::move(*value_variant));
BKE_volume_grid_remove(volume, grid); params.set_output("Volume", std::move(geometry_set));
}
params.set_output("Grid", bke::GVolumeGrid(grid));
params.set_output("Volume", geometry_set);
return; return;
} }
} }
if (!grid_name.empty()) {
params.error_message_add(NodeWarningType::Warning,
"No supported grid found with the given name");
}
if (std::optional<VolumeGridType> 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 #else
node_geo_exec_with_missing_openvdb(params); node_geo_exec_with_missing_openvdb(params);
#endif #endif