mirror of
https://github.com/OrcaSlicer/OrcaSlicer.git
synced 2026-10-08 00:01:09 +00:00
Belt printer: get the branch CI green (Windows Polyline clash, validator belt slice) (#16262)
Two one-file fixes that get `belt-printer`'s CI green again after
#16236; both failures are mine.
## Changes
1. **Tests: qualify `Polyline` in the belt overhang test for Windows.**
Both Windows builds fail at `tests/fff_print/test_print.cpp:1398`
("reference to 'Polyline' is ambiguous"): the GDI function of the same
name, like the `Polygon` fix in #16196. `Slic3r::Polyline`.
2. **Profile validator: slice belt printers with two cubes along the
belt.** The slice check (`-s`) prints one cube per printer with a height
range 4–10 on filament 2 and, on belt printers, expects a plain `T1`.
Since #16236 a belt object's slicing Z starts at the belt below its
leading end, well below the part's first printed layer, so that range
falls into the empty lead-in and filament 2 is never used; all six belt
printers reported "the filament change never fired". Belt printers are
now sliced with two cubes one behind the other along the belt, the
second on filament 2. Other printers are unchanged.
## Tests
- Root cause for both confirmed in the upstream logs (run 37583336264
and the push run on 0b11311d40) and reproduced locally with the rebuilt
validator.
- `OrcaSlicer_profile_validator -s -l 2`: Printcepts 8/8, IdeaFormer
8/8, Custom 20/20 (the four MyBeltPrinter nozzles included), Prusa 95/95
as a non-belt control.
- `fff_print_tests` and `libslic3r_tests` pass;
`scripts/clang_tidy_diff.py --base upstream/belt-printer`: no findings.
- A fork run of Build all with these two commits on top of belt-printer
(plus a pending belt change) was green on every job: Windows x64 and
arm64 builds, Slice check, unit tests on Linux x86_64, Linux aarch64,
macOS arm64, Windows x64, Windows arm64 and both Flatpaks:
https://github.com/HarrierPigeon/OrcaSlicer/actions/runs/37607869527
- Written with Claude Code; reviewed and run by me.
This commit is contained in:
@@ -202,6 +202,7 @@ Vec2d place_wipe_tower(DynamicPrintConfig &cfg, const Vec2d ¢er)
|
||||
std::string slice_two_color_cube_and_export(DynamicPrintConfig cfg, bool is_bbl, bool by_object)
|
||||
{
|
||||
const Vec2d center = printable_area_center(cfg);
|
||||
const bool belt = cfg.opt_bool("belt_printer");
|
||||
std::vector<Vec2d> cube_mins;
|
||||
if (by_object) {
|
||||
// By-object printing fires the hook only without a wipe tower, and rules out clumping detection and
|
||||
@@ -212,6 +213,12 @@ std::string slice_two_color_cube_and_export(DynamicPrintConfig cfg, bool is_bbl,
|
||||
cfg.set_key_value("timelapse_type", new ConfigOptionEnum<TimelapseType>(tlTraditional));
|
||||
cfg.set_key_value("skirt_loops", new ConfigOptionInt(0));
|
||||
cube_mins = {center + Vec2d(-20., -5.), center + Vec2d(10., -5.)};
|
||||
} else if (belt) {
|
||||
// A belt object's slicing Z starts at the belt below its leading end, well below its first
|
||||
// printed layer, so a height range in slicing Z does not map onto the part. Two cubes one
|
||||
// behind the other along the belt, the second on filament 2, give the one filament change
|
||||
// instead (the purge prism is an object the GUI adds, so there is no tower to place).
|
||||
cube_mins = {center - Vec2d(5., 15.), center + Vec2d(-5., 5.)};
|
||||
} else {
|
||||
// Clumping detection changes the tower footprint, so turn it on before placing the tower.
|
||||
if (!cfg.opt_string("wrapping_detection_gcode").empty())
|
||||
@@ -229,14 +236,20 @@ std::string slice_two_color_cube_and_export(DynamicPrintConfig cfg, bool is_bbl,
|
||||
obj->name = "cube"; // populates [input_filename_base] the way a loaded model does
|
||||
obj->add_volume(m);
|
||||
obj->add_instance();
|
||||
// Filament 2 is used only above z=4, so the upper layers carry a single filament change.
|
||||
DynamicPrintConfig range_config;
|
||||
range_config.set_key_value("extruder", new ConfigOptionInt(2));
|
||||
// Every range must carry a layer_height; use the process's own so a fine nozzle (e.g. 0.15 mm
|
||||
// printing ~0.1 mm layers) isn't forced to a height its extrusion width can't support - that
|
||||
// trips Flow::with_spacing.
|
||||
range_config.set_key_value("layer_height", new ConfigOptionFloat(cfg.opt_float("layer_height")));
|
||||
obj->layer_config_ranges[{4.0, 10.0}].assign_config(std::move(range_config));
|
||||
if (belt && !by_object) {
|
||||
// The second cube along the belt is on filament 2 (see cube_mins above).
|
||||
if (&cube_min == &cube_mins.back())
|
||||
obj->config.set_key_value("extruder", new ConfigOptionInt(2));
|
||||
} else {
|
||||
// Filament 2 is used only above z=4, so the upper layers carry a single filament change.
|
||||
DynamicPrintConfig range_config;
|
||||
range_config.set_key_value("extruder", new ConfigOptionInt(2));
|
||||
// Every range must carry a layer_height; use the process's own so a fine nozzle (e.g. 0.15 mm
|
||||
// printing ~0.1 mm layers) isn't forced to a height its extrusion width can't support - that
|
||||
// trips Flow::with_spacing.
|
||||
range_config.set_key_value("layer_height", new ConfigOptionFloat(cfg.opt_float("layer_height")));
|
||||
obj->layer_config_ranges[{4.0, 10.0}].assign_config(std::move(range_config));
|
||||
}
|
||||
obj->ensure_on_bed();
|
||||
print.auto_assign_extruders(obj);
|
||||
}
|
||||
|
||||
@@ -1395,7 +1395,7 @@ TEST_CASE("Belt supports reach the belt under a leading overhang", "[Print][belt
|
||||
REQUIRE(lowest != nullptr);
|
||||
double floor_under_lowest = std::numeric_limits<double>::max();
|
||||
for (const ExtrusionEntity *entity : lowest->support_fills.flatten().entities)
|
||||
for (const Polyline &pl : entity->as_polylines())
|
||||
for (const Slic3r::Polyline &pl : entity->as_polylines())
|
||||
for (const Point &pt : pl.points)
|
||||
floor_under_lowest = std::min(floor_under_lowest, floor.floor_print_z(pt));
|
||||
// The object's lowest geometry. The slicing frame starts at the lowest
|
||||
|
||||
Reference in New Issue
Block a user