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:
@@ -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<SocketValueVariant> 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<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)
|
||||
{
|
||||
#ifdef WITH_OPENVDB
|
||||
@@ -50,25 +89,29 @@ static void node_geo_exec(GeoNodeExecParams params)
|
||||
GeometrySet geometry_set = params.extract_input<GeometrySet>("Volume");
|
||||
const std::string grid_name = params.extract_input<std::string>("Name");
|
||||
const bool remove_grid = params.extract_input<bool>("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<SocketValueVariant> 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<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
|
||||
node_geo_exec_with_missing_openvdb(params);
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user