diff --git a/src/libslic3r/GCode.cpp b/src/libslic3r/GCode.cpp index 360e35cae2..45910cae00 100644 --- a/src/libslic3r/GCode.cpp +++ b/src/libslic3r/GCode.cpp @@ -8507,14 +8507,25 @@ 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; - } + // Belt printers: tell the cooling buffer which band above the belt the next extrusion is + // in (CoolingBuffer::apply_belt_band_fan consumes the tag). A tilted layer runs from the + // belt to the top of the part, so this is decided per segment, not per path; a tag is + // written once per layer and at every change, capped where the fan stops depending on it. + const bool belt_band_tags = m_enable_cooling_markers && m_config.belt_printer.value; + const int belt_band_cap = belt_band_tags + ? std::max(m_config.close_fan_the_first_x_layers.get_at(m_writer->filament()->id()), + m_config.full_fan_speed_layer.get_at(m_writer->filament()->id())) + 1 : 0; + auto tag_belt_band = [this, &gcode, belt_band_tags, belt_band_cap, z = path_point_mm.z()](coord_t x, coord_t y) { + if (! belt_band_tags) + return; + const int band = std::min(this->effective_layer_index_for_point(Vec3d(unscale(x), unscale(y), z)), belt_band_cap); + if (m_belt_band_tag_layer != m_layer_index || m_belt_band_tag != band) { + gcode += ";_BELT_BAND:" + std::to_string(band) + "\n"; + m_belt_band_tag = band; + m_belt_band_tag_layer = m_layer_index; + } + }; + tag_belt_band(path.first_point().x(), path.first_point().y()); 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 @@ -8999,6 +9010,7 @@ std::string GCode::_extrude(const ExtrusionPath &path, std::string description, tempDescription += Slic3r::format(" | Old Flow Value: %0.5f Length: %0.5f",oldE, line_length); } } + tag_belt_band((line.a.x() + line.b.x()) / 2, (line.a.y() + line.b.y()) / 2); if (path.z_contoured) { // ZAA: Z anti-aliased extrusion with variable Z per point Vec2d dest2d = this->point_to_gcode(line.b.to_point()); @@ -9129,6 +9141,7 @@ std::string GCode::_extrude(const ExtrusionPath &path, std::string description, const ProcessedPoint &processed_point = new_points[i]; const ProcessedPoint &pre_processed_point = new_points[i-1]; Vec3d p = this->point_to_gcode_quantized(processed_point.p); + tag_belt_band((pre_processed_point.p.x() + processed_point.p.x()) / 2, (pre_processed_point.p.y() + processed_point.p.y()) / 2); if (m_enable_cooling_markers) { if (enable_overhang_bridge_fan) { cur_fan_enabled = check_overhang_fan(processed_point.overlap, path.role());