From f2a11928f63f371c92ad8f4a33ae35379e06d3bb Mon Sep 17 00:00:00 2001 From: Hanif Koh Date: Fri, 11 Sep 2026 20:25:08 +0800 Subject: [PATCH] Read the Belt Tilt Only from the Belt G-code Header Every printer's config block lists belt_slice_rotation_angle (default 45), so the processor marked all G-code as belt G-code: imported flat G-code got the belt view on a belt printer, and the belt-only Z handling in the processor ran for non-belt prints whose config block precedes the body. Take the angle only from outside the config block, where only the belt header writes it. --- src/libslic3r/GCode/GCodeProcessor.cpp | 16 +++++++-- src/libslic3r/GCode/GCodeProcessor.hpp | 1 + tests/fff_print/CMakeLists.txt | 1 + tests/fff_print/test_gcode_processor.cpp | 46 ++++++++++++++++++++++++ 4 files changed, 62 insertions(+), 2 deletions(-) create mode 100644 tests/fff_print/test_gcode_processor.cpp diff --git a/src/libslic3r/GCode/GCodeProcessor.cpp b/src/libslic3r/GCode/GCodeProcessor.cpp index b2477437b0..33d5b96876 100644 --- a/src/libslic3r/GCode/GCodeProcessor.cpp +++ b/src/libslic3r/GCode/GCodeProcessor.cpp @@ -3586,6 +3586,7 @@ void GCodeProcessor::reset() m_zero_layer_height = 0.0f; m_first_layer_height = 0.0f; m_processing_start_custom_gcode = false; + m_in_config_block = false; m_g1_line_id = 0; m_layer_id = 0; m_cp_color.reset(); @@ -4191,9 +4192,20 @@ void GCodeProcessor::process_tags(const std::string_view comment, bool producers return; } + if (boost::starts_with(comment, " CONFIG_BLOCK_START")) { + m_in_config_block = true; + return; + } + if (boost::starts_with(comment, " CONFIG_BLOCK_END")) { + m_in_config_block = false; + return; + } + // Belt printer: derive the physical tilt magnitude from the slicing-rotation - // angle header comment (used to enable the preview's belt view). - if (boost::starts_with(comment, " belt_slice_rotation_angle = ")) { + // angle header comment (used to enable the preview's belt view). Only the belt + // header carries it outside the config block; the config block lists the key + // for every printer, belt or not. + if (!m_in_config_block && boost::starts_with(comment, " belt_slice_rotation_angle = ")) { try { m_result.belt_tilt_angle = std::abs(std::stof(std::string(comment.substr(29)))); } catch (...) {} diff --git a/src/libslic3r/GCode/GCodeProcessor.hpp b/src/libslic3r/GCode/GCodeProcessor.hpp index 0a8a35a88b..85cc5a7544 100644 --- a/src/libslic3r/GCode/GCodeProcessor.hpp +++ b/src/libslic3r/GCode/GCodeProcessor.hpp @@ -1194,6 +1194,7 @@ class Print; float m_first_layer_height; // mm float m_zero_layer_height; // mm bool m_processing_start_custom_gcode; + bool m_in_config_block; unsigned int m_g1_line_id; unsigned int m_layer_id; CpColor m_cp_color; diff --git a/tests/fff_print/CMakeLists.txt b/tests/fff_print/CMakeLists.txt index 3247bfda66..59e065ecb8 100644 --- a/tests/fff_print/CMakeLists.txt +++ b/tests/fff_print/CMakeLists.txt @@ -8,6 +8,7 @@ add_executable(${_TEST_NAME}_tests test_extrusion_processor.cpp test_fill.cpp test_flow.cpp + test_gcode_processor.cpp test_gcode_timing.cpp test_gcodewriter.cpp test_model.cpp diff --git a/tests/fff_print/test_gcode_processor.cpp b/tests/fff_print/test_gcode_processor.cpp new file mode 100644 index 0000000000..3998b65547 --- /dev/null +++ b/tests/fff_print/test_gcode_processor.cpp @@ -0,0 +1,46 @@ +#include + +#include "libslic3r/libslic3r.h" +#include "libslic3r/GCode/GCodeProcessor.hpp" +#include "libslic3r/PrintConfig.hpp" + +#include "test_utils.hpp" + +#include +#include + +using namespace Slic3r; +using Catch::Matchers::WithinAbs; + +namespace { + +float processed_belt_tilt(const std::string &gcode) +{ + ScopedTemporaryFile temp(".gcode"); + { + std::ofstream os(temp.string()); + os << gcode; + } + GCodeProcessor proc; + proc.apply_config(FullPrintConfig{}); + proc.process_file(temp.string()); + return proc.get_result().belt_tilt_angle; +} + +constexpr const char *body = "G1 X10 Y10 Z0.2 F3000\nG1 X20 Y10 E1 F1200\n"; + +} // namespace + +TEST_CASE("The config block's belt angle does not mark G-code as belt G-code", "[GCodeProcessor][belt]") +{ + // Every printer's config block lists belt_slice_rotation_angle (default 45), belt or not. + const std::string gcode = std::string("; CONFIG_BLOCK_START\n; belt_printer = 0\n; belt_slice_rotation_angle = 45\n; CONFIG_BLOCK_END\n") + body; + CHECK_THAT(processed_belt_tilt(gcode), WithinAbs(0., 1e-6)); +} + +TEST_CASE("The belt header's angle marks G-code as belt G-code", "[GCodeProcessor][belt]") +{ + const std::string gcode = std::string("; belt_slice_rotation_angle = -45.0\n") + body + + "; CONFIG_BLOCK_START\n; belt_printer = 1\n; belt_slice_rotation_angle = -45\n; CONFIG_BLOCK_END\n"; + CHECK_THAT(processed_belt_tilt(gcode), WithinAbs(45., 1e-6)); +}