feat(gui): enable Hybrid nozzle flow for multi-sub-nozzle extruders

An extruder with more than one physical sub-nozzle can hold a mix of
Standard and High Flow nozzles. The Flow dropdown now offers Hybrid for
such extruders (extruder_max_nozzle_count > 1, nil-guarded); grouping
already expands a Hybrid extruder into per-volume nozzle groups from
extruder_nozzle_stats.

- sidebar Flow combo offers Hybrid only for multi-sub-nozzle extruders
- preset lookup treats Hybrid as Standard (presets define no Hybrid
  variant); variant strings are never fabricated for it
- printer tab splits a Hybrid extruder into Standard + High Flow rows,
  with matching selection-index arithmetic and sync-enable rules
- syncing from a printer whose extruder holds mixed nozzle flows now
  selects Hybrid instead of collapsing to the dominant flow type
- send-to-printer flow check: a nozzle-rack extruder validates its
  nozzle inventory (mounted + rack) against every needed flow instead
  of comparing only the mounted nozzle; mounted-flow lookup is now
  per-extruder, fixing an index shift when a nozzle reports no flow
- Hybrid is session-only in app config (stored as Standard), so a
  fresh session starts from concrete flow types

Printers whose extruders have a single sub-nozzle (including all
dual-extruder machines without a rack) see no new option and identical
check behavior.
This commit is contained in:
SoftFever
2026-07-10 18:02:26 +08:00
parent 83d2d4179d
commit c528d3a0bc
6 changed files with 145 additions and 121 deletions

View File

@@ -638,7 +638,8 @@ std::string get_extruder_variant_string(ExtruderType extruder_type, NozzleVolume
//extruder_type = etDirectDrive;
return variant_string;
}
if (nozzle_volume_type > nvtMaxNozzleVolumeType) {
auto nozzle_volume_types = get_valid_nozzle_volume_type();
if (nozzle_volume_types.count(nozzle_volume_type) == 0) {
BOOST_LOG_TRIVIAL(error) << __FUNCTION__ << boost::format(", unsupported NozzleVolumeType=%1%")%nozzle_volume_type;
//extruder_type = etDirectDrive;
return variant_string;
@@ -9679,6 +9680,9 @@ int DynamicPrintConfig::get_index_for_extruder(int extruder_or_filament_id, std:
if (variant_opt != nullptr) {
int v_size = variant_opt->values.size();
const bool has_complete_id_map = id_opt && int(id_opt->values.size()) >= v_size;
// nvtHybrid not supported in presets, switch to nvtStandard to match the preset values
if (nozzle_volume_type == nvtHybrid)
nozzle_volume_type = nvtStandard;
std::string extruder_variant = get_extruder_variant_string(extruder_type, nozzle_volume_type);
for (int index = 0; index < v_size; index++)
{