Belt: drive the first-layer fan band from the generator, not from parsed moves

The cooling buffer's band pass rebuilt positions from the layer's G-code
and tested them against the first-layer plane. The G-code is in machine
coordinates and the plane is in slicing coordinates, so on the shipped
profiles the nearest move was over 100 mm from a 0.2 mm band and the pass
never changed the fan. GCode::_extrude() already knows each path's height
above the belt, so it now tags the band changes and the buffer applies and
strips the tags.

The pass also took the S of every M106 as the part fan, whatever its P
index, and stored that 0..255 value where a percentage was expected (an
auxiliary fan line came back as M106 S651); it now uses FanMover's parser,
which ignores other fans, and converts to percent. It no longer overwrites
the layer's intended speed, only the fan's actual state.

Raised in Hanif Koh's review of #14394.
This commit is contained in:
harrierpigeon
2026-10-02 01:10:57 -05:00
parent 646fe6384c
commit 556569c0e3
6 changed files with 141 additions and 174 deletions
+8
View File
@@ -8507,6 +8507,14 @@ std::string GCode::_extrude(const ExtrusionPath &path, std::string description,
// the speed fade tracks perpendicular distance from the plane on
// belt printers; otherwise this falls back to the slicing layer id.
const int _layer = this->effective_layer_index_for_point(path_point_mm);
// Belt printers: tell the cooling buffer which band above the belt this path starts in,
// once per layer and at every change (CoolingBuffer::apply_belt_band_fan consumes it).
if (m_enable_cooling_markers && m_config.belt_printer.value &&
(m_belt_band_tag_layer != m_layer_index || m_belt_band_tag != _layer)) {
gcode += ";_BELT_BAND:" + std::to_string(_layer) + "\n";
m_belt_band_tag = _layer;
m_belt_band_tag_layer = m_layer_index;
}
if (path_on_first_layer || object_layer_over_raft()) {
//BBS: for solid infill of first layer, speed can be higher as long as
//wall lines have be attached