Merge upstream/main into belt-printer

Brings belt-printer up to main 4b4a261787. Resolutions:

- G-code header (#15897, #15915): main moved the header, config and
  thumbnail block later in _do_export; write_belt_header() moves with it,
  still after the thumbnails and outside the BTT_TFT gate.
- _extrude: first-layer acceleration keeps the per-path first-layer plane
  test with main's cached nozzle index (#16028); main's set_speed out-param
  form (#16108) everywhere else.
- GCodeWriter (#16108): the arc-to-polyline fallback for machine mappings
  that cannot express G2/G3 now runs in the out-param extrude_arc_to_xy,
  which is the overload GCode calls, and appends to the caller's string.
- GCodeProcessorResult: the belt fields join main's forwarding assign.
- Clipper2 (#15969): belt arrange helpers take Slic3r::Point; the tree
  support join types lose their ClipperLib qualifier.
- CLI arrange (#15837): belt printers still reserve no wipe tower.
- Wipe tower options (#15841): the two new sparse-layer toggles are hidden
  for belt printers like the rest of the tower options.
- Keyboard shortcuts (#15706): main's registry replaces the old key switch;
  the belt view toggle is re-registered in the next commit.
- Print::process: the belt purge-plan undo runs before main's SliceStarted
  event.
- scripts/filament_id_snapshot.json: deleted on main (a77209af8f).
- Includes and appended tests: union of both sides.
This commit is contained in:
harrierpigeon
2026-10-04 19:20:33 -05:00
11471 changed files with 2992690 additions and 2720441 deletions
+39 -8
View File
@@ -12,21 +12,48 @@
#include "BuildVolume.hpp"
#include "ClipperUtils.hpp"
#include "EdgeGrid.hpp"
#include "libslic3r/Exception.hpp"
#include "libslic3r/ExPolygon.hpp"
#include "Fill/Fill.hpp"
#include "libslic3r/Flow.hpp"
#include "libslic3r/Fill/FillBase.hpp"
#include "Layer.hpp"
#include "libslic3r/Point.hpp"
#include "libslic3r/Line.hpp"
#include "Print.hpp"
#include "MultiPoint.hpp"
#include "Polygon.hpp"
#include "Polyline.hpp"
#include "MutablePolygon.hpp"
#include "BeltFloorContext.hpp"
#include "libslic3r/Support/TreeSupportCommon.hpp"
#include "libslic3r/PrintConfig.hpp"
#include "libslic3r/Support/TreeModelVolumes.hpp"
#include "libslic3r/Support/SupportParameters.hpp"
#include "libslic3r/Support/SupportLayer.hpp"
#include "SupportCommon.hpp"
#include "libslic3r/Surface.hpp"
#include "TriangleMeshSlicer.hpp"
#include "TreeSupport.hpp"
#include "I18N.hpp"
#include "libslic3r/libslic3r.h"
#include "libslic3r/Utils.hpp"
#include <algorithm>
#include <Eigen/Geometry>
#include <atomic>
#include <cassert>
#include <chrono>
#include <cstdint>
#include <functional>
#include <cstdlib>
#include <cmath>
#include <limits>
#include <memory>
#include <math.h>
#include <mutex>
#include <numeric>
#include <iterator>
#include <optional>
#include <stdio.h>
#include <string>
@@ -37,6 +64,10 @@
#include <tbb/parallel_for.h>
#include <tbb/parallel_for_each.h>
#include <tbb/spin_mutex.h>
#include <vector>
#include <utility>
#include <unordered_set>
#include <tuple>
#if defined(TREE_SUPPORT_SHOW_ERRORS) && defined(_WIN32)
#define TREE_SUPPORT_SHOW_ERRORS_WIN32
@@ -69,7 +100,7 @@ static inline void validate_range(const Point &pt)
{
static constexpr const int32_t hi = 65536 * 16384;
if (pt.x() > hi || pt.y() > hi || -pt.x() > hi || -pt.y() > hi)
throw ClipperLib::clipperException("Coordinate outside allowed range");
throw RuntimeError("Coordinate outside allowed range");
}
static inline void validate_range(const Points &points)
@@ -844,16 +875,16 @@ static std::optional<std::pair<Point, size_t>> polyline_sample_next_point_at_dis
}
// offset in steps
for (int i = 0; i < steps; ++ i) {
ret = diff(offset(ret, step_size, ClipperLib::jtRound, scaled<float>(0.01)), collision_trimmed());
ret = diff(offset(ret, step_size, jtRound, scaled<float>(0.01)), collision_trimmed());
// ensure that if many offsets are done the performance does not suffer extremely by the new vertices of jtRound.
if (i % 10 == 7)
ret = polygons_simplify(ret, scaled<double>(0.015), polygons_strictly_simple);
ret = polygons_simplify(ret, scaled<double>(0.015));
}
// offset the remainder
float last_offset = distance - steps * step_size;
if (last_offset > SCALED_EPSILON)
ret = offset(ret, distance - steps * step_size, ClipperLib::jtRound, scaled<float>(0.01));
ret = polygons_simplify(ret, scaled<double>(0.015), polygons_strictly_simple);
ret = offset(ret, distance - steps * step_size, jtRound, scaled<float>(0.01));
ret = polygons_simplify(ret, scaled<double>(0.015));
if (do_final_difference)
ret = diff(ret, collision_trimmed());
@@ -1634,8 +1665,8 @@ static Point move_inside_if_outside(const Polygons &polygons, Point from, int di
safe_movement_distance, safe_movement_distance + radius, 1);
}
if (settings.no_error && settings.move)
// as ClipperLib::jtRound has to be used for offsets this simplify is VERY important for performance.
polygons_simplify(increased, scaled<float>(0.025), polygons_strictly_simple);
// as jtRound has to be used for offsets this simplify is VERY important for performance.
polygons_simplify(increased, scaled<float>(0.025));
} else
// if no movement is done the areas keep parent area as no move == offset(0)
increased = parent.influence_area;
@@ -4247,7 +4278,7 @@ void organic_draw_branches(
base_layer_polygons = smooth_outward(union_(base_layer_polygons), config.support_line_width); //FIXME was .smooth(50);
//smooth_outward(closing(std::move(bottom), closing_distance + minimum_island_radius, closing_distance, SUPPORT_SURFACES_OFFSET_PARAMETERS), smoothing_distance) :
// simplify a bit, to ensure the output does not contain outrageous amounts of vertices. Should not be necessary, just a precaution.
base_layer_polygons = polygons_simplify(base_layer_polygons, std::min(scaled<double>(0.03), double(config.resolution)), polygons_strictly_simple);
base_layer_polygons = polygons_simplify(base_layer_polygons, std::min(scaled<double>(0.03), double(config.resolution)));
}
// Subtract top contact layer polygons from support base.