diff --git a/src/libslic3r/GCode/ToolOrdering.cpp b/src/libslic3r/GCode/ToolOrdering.cpp index ee03d6e959..65c887f343 100644 --- a/src/libslic3r/GCode/ToolOrdering.cpp +++ b/src/libslic3r/GCode/ToolOrdering.cpp @@ -138,7 +138,8 @@ static double calc_max_layer_height(const PrintConfig &config, double max_object { double max_layer_height = std::numeric_limits::max(); for (size_t i = 0; i < config.nozzle_diameter.values.size(); ++ i) { - double mlh = config.max_layer_height.values[i]; + // max_layer_height may be shorter than the extruder count; get_at() clamps. + double mlh = config.max_layer_height.get_at(i); if (mlh == 0.) mlh = 0.75 * config.nozzle_diameter.values[i]; max_layer_height = std::min(max_layer_height, mlh); diff --git a/tests/fff_print/test_multifilament.cpp b/tests/fff_print/test_multifilament.cpp index 12c1cae766..f33a8e1e61 100644 --- a/tests/fff_print/test_multifilament.cpp +++ b/tests/fff_print/test_multifilament.cpp @@ -85,3 +85,22 @@ TEST_CASE("Per-object wall filament override is honored", "[MultiFilament]") CHECK(tools_for_role(gcode, "perimeter") == std::set{ 0, 1 }); CHECK(tools_for_role(gcode, "infill") == std::set{ 0 }); // infill not overridden: stays on F1 } + +// max_layer_height can be shorter than the extruder count (normalization sizes it to the +// filament count under single_extruder_multi_material). calc_max_layer_height() in ToolOrdering +// indexed it per-nozzle and read past the end. Shortened directly here to isolate that read; +// the other per-extruder keys stay extruder-length so slicing reaches the code under test. +TEST_CASE("Multi-extruder slice stays in bounds with a short max_layer_height", "[MultiFilament]") +{ + DynamicPrintConfig config = multifilament_config(2); + config.set_deserialize_strict({ + { "nozzle_diameter", "0.4,0.4" }, + { "printer_extruder_id", "1,2" }, + { "printer_extruder_variant", "Direct Drive Standard,Direct Drive Standard" }, + { "extruder_printable_height", "0,0" }, + { "max_layer_height", "0.3" }, // deliberately one entry short + }); + Print print; + init_and_process_print({ cube(20) }, print, config); + REQUIRE_FALSE(print.objects().front()->layers().empty()); +}