From caa15491c3694dc4f003fe79ed0410ed85eef205 Mon Sep 17 00:00:00 2001 From: Kiss Lorand <50251547+kisslorand@users.noreply.github.com> Date: Sat, 19 Sep 2026 19:19:54 +0300 Subject: [PATCH] Fix duplicate timelapse G-code on i3 printers (#15734) --- src/libslic3r/GCode.cpp | 2 +- tests/fff_print/test_print.cpp | 49 ++++++++++++++++++++++++++++++++++ 2 files changed, 50 insertions(+), 1 deletion(-) diff --git a/src/libslic3r/GCode.cpp b/src/libslic3r/GCode.cpp index 81fc81b488..d9cc1d4a11 100644 --- a/src/libslic3r/GCode.cpp +++ b/src/libslic3r/GCode.cpp @@ -5628,7 +5628,7 @@ LayerResult GCode::process_layer( m_layer = &layer; m_object_layer_over_raft = false; - if (!m_config.time_lapse_gcode.value.empty() && !is_BBL_Printer()) { + if (!need_insert_timelapse_gcode_for_traditional && !m_config.time_lapse_gcode.value.empty() && !is_BBL_Printer()) { DynamicConfig config; config.set_key_value("layer_num", new ConfigOptionInt(m_layer_index)); config.set_key_value("layer_z", new ConfigOptionFloat(print_z)); diff --git a/tests/fff_print/test_print.cpp b/tests/fff_print/test_print.cpp index 6bff945fc3..d7cd965343 100644 --- a/tests/fff_print/test_print.cpp +++ b/tests/fff_print/test_print.cpp @@ -22,10 +22,59 @@ #include #include #include +#include using namespace Slic3r; using namespace Slic3r::Test; +TEST_CASE("Timelapse g-code is emitted once per layer for Bambu and non-Bambu printers", "[Print][Regression]") +{ + struct PrinterCase { + std::string name; + std::string structure; + bool is_bbl; + }; + const PrinterCase printer = GENERATE(from_range(std::vector{ + { "non-BBL undefined", "undefine", false }, + { "non-BBL CoreXY", "corexy", false }, + { "non-BBL i3", "i3", false }, + { "non-BBL H-Bot", "hbot", false }, + { "non-BBL Delta", "delta", false }, + { "Bambu CoreXY", "corexy", true }, + { "Bambu i3", "i3", true }, + })); + INFO("printer: " << printer.name); + + DynamicPrintConfig config = DynamicPrintConfig::full_print_config(); + config.set_deserialize_strict({ + { "initial_layer_print_height", 0.2 }, + { "layer_change_gcode", ";TEST_LAYER_CHANGE" }, + { "layer_height", 0.2 }, + { "printer_structure", printer.structure }, + { "spiral_mode", false }, + { "time_lapse_gcode", "TIMELAPSE_TAKE_FRAME" }, + }); + Print print; + print.is_BBL_printer() = printer.is_bbl; + Model model; + init_print({ cube(20) }, print, model, config); + const std::string gcode = Slic3r::Test::gcode(print); + + const auto count = [&gcode](std::string_view token) { + size_t occurrences = 0; + size_t pos = 0; + while ((pos = gcode.find(token, pos)) != std::string::npos) { + ++occurrences; + pos += token.size(); + } + return occurrences; + }; + + const size_t layer_changes = count("\n;TEST_LAYER_CHANGE\n"); + REQUIRE(layer_changes > 0); + CHECK(count("\nTIMELAPSE_TAKE_FRAME\n") == layer_changes); +} + SCENARIO("Changing the number of solid shell layers does not make all surfaces internal", "[Print]") { GIVEN("sliced 20mm cube and config with top_shell_layers = 2 and bottom_shell_layers = 1") { Slic3r::DynamicPrintConfig config = Slic3r::DynamicPrintConfig::full_print_config();