From a83cd8aa296e5415311515ceb7b5b3ddedea4903 Mon Sep 17 00:00:00 2001 From: harrierpigeon Date: Mon, 29 Jun 2026 02:58:58 -0500 Subject: [PATCH] Fix belt printer phantom extrusion line from Y=0 in preview On a belt printer the sliced preview drew a stray extrusion-colored line from Y~=0 to the model, rendered in the first extrusion role's color. It is not a travel and does not occur on non-belt printers. GCodeProcessor::store_move_vertex pins a move's stored Z to the first-layer height during the start-G-code "prepare" stage. That is a harmless cosmetic tidy-up on a normal printer, but on a belt printer the designed-view back-transform couples machine Z into the rendered model Y (the belt tilt mixes the height and belt-feed axes). Pinning Z back-transforms the last prepare-stage move (the unretract before the first extrusion) to model Y ~= 0, and libvgcode then draws a phantom extrusion segment from Y ~= 0 to the first real toolpath. Keep the real Z for belt printers (gated on belt_tilt_angle, parsed from the G-code header before the body) so prepare-stage moves back-transform correctly. Non-belt processing is byte-identical. The emitted G-code was already correct; this is a preview-geometry fix. --- src/libslic3r/GCode/GCodeProcessor.cpp | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/src/libslic3r/GCode/GCodeProcessor.cpp b/src/libslic3r/GCode/GCodeProcessor.cpp index 9cad57e693..43536c30b9 100644 --- a/src/libslic3r/GCode/GCodeProcessor.cpp +++ b/src/libslic3r/GCode/GCodeProcessor.cpp @@ -7067,6 +7067,22 @@ void GCodeProcessor::store_move_vertex(EMoveType type, EMovePathType path_type, m_result.print_statistics.total_travel_distance += m_travel_dist; } + // During the start G-code "prepare" stage the toolhead Z is not yet a real + // print height on a normal printer, so it is pinned to the first-layer height + // to keep the preview tidy. Belt printers are the exception: there the Z is + // written explicitly by BeltGCodeWriter and the designed-view back-transform + // couples machine Z into the rendered model Y (the belt tilt mixes the height + // and belt-feed axes). Overriding Z therefore back-transforms the last + // prepare-stage move (the unretract before the first extrusion) to model + // Y ~= 0, and the libvgcode path builder then draws a phantom extrusion + // segment from Y ~= 0 to the first real toolpath. Keep the real Z for belt + // printers so prepare-stage moves map correctly. Gated on belt_tilt_angle (set + // from the G-code header before the body is processed) so non-belt processing + // is byte-identical. + const float store_z = (m_processing_start_custom_gcode && m_result.belt_tilt_angle == 0.f) + ? m_first_layer_height + : m_end_position[Z] - m_z_offset; + m_result.moves.push_back({ m_last_line_id, type, @@ -7074,7 +7090,7 @@ void GCodeProcessor::store_move_vertex(EMoveType type, EMovePathType path_type, static_cast(filament_id), m_cp_color.current, //BBS: add plate's offset to the rendering vertices - Vec3f(m_end_position[X] + m_x_offset, m_end_position[Y] + m_y_offset, m_processing_start_custom_gcode ? m_first_layer_height : m_end_position[Z]- m_z_offset) + m_extruder_offsets[filament_id], + Vec3f(m_end_position[X] + m_x_offset, m_end_position[Y] + m_y_offset, store_z) + m_extruder_offsets[filament_id], static_cast(m_end_position[E] - m_start_position[E]), m_feedrate, 0.0f, // actual feedrate