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