feat(slicing): enforce filament flow-type restrictions in auto grouping

Filament grouping already consumed per-filament forbidden nozzle volume
types, but every call site passed an empty map, so a variant-restricted
filament (e.g. one limited to "Direct Drive TPU High Flow") could be
auto-grouped onto an incompatible nozzle flow type on multi-variant
printers.

- add convert_to_nvt_type() to parse extruder variant strings
- add Print::get_filament_unprintable_flow(): forbidden volume types =
  printer extruder variants minus the filament's declared variants;
  filaments declaring no variants stay unrestricted
- feed the map into grouping at the by-object path (Print.cpp) and all
  six mapping/planning sites in reorder_extruders_for_minimum_flush_volume
- unit-test the string parser

Non-restricted configurations produce an empty map, so existing
printers' grouping and g-code are unchanged.
This commit is contained in:
SoftFever
2026-07-10 15:10:46 +08:00
parent 9e8ac03476
commit b2eeed2622
7 changed files with 121 additions and 7 deletions

View File

@@ -21,6 +21,7 @@ add_executable(${_TEST_NAME}_tests
test_polygon.cpp
test_mutable_polygon.cpp
test_mutable_priority_queue.cpp
test_nozzle_volume_type.cpp
test_stl.cpp
test_meshboolean.cpp
test_marchingsquares.cpp

View File

@@ -0,0 +1,31 @@
#include <catch2/catch_all.hpp>
#include "libslic3r/PrintConfig.hpp"
using namespace Slic3r;
TEST_CASE("convert_to_nvt_type maps extruder variant strings to nozzle volume types", "[Config]")
{
SECTION("Direct Drive variants") {
REQUIRE(convert_to_nvt_type("Direct Drive Standard") == nvtStandard);
REQUIRE(convert_to_nvt_type("Direct Drive High Flow") == nvtHighFlow);
REQUIRE(convert_to_nvt_type("Direct Drive TPU High Flow") == nvtTPUHighFlow);
}
SECTION("Bowden variants") {
REQUIRE(convert_to_nvt_type("Bowden Standard") == nvtStandard);
REQUIRE(convert_to_nvt_type("Bowden High Flow") == nvtHighFlow);
}
SECTION("Unparsable strings fall back to hybrid") {
REQUIRE(convert_to_nvt_type("Unknown Extruder") == nvtHybrid);
REQUIRE(convert_to_nvt_type("") == nvtHybrid);
REQUIRE(convert_to_nvt_type("High Flow") == nvtHybrid);
REQUIRE(convert_to_nvt_type("Direct Drive") == nvtHybrid);
}
SECTION("Whitespace around the volume-type remainder is trimmed") {
REQUIRE(convert_to_nvt_type("Direct Drive High Flow ") == nvtHighFlow);
REQUIRE(convert_to_nvt_type(" Bowden Standard") == nvtStandard);
}
}