The U1's heated bed tops out at 100 °C, but these profiles requested
105-110 °C, which leads to print errors unless the user modifies the
printer's firmware configuration.
Affected profiles:
- Snapmaker ABS @U1 base (110/105 → 100)
- Snapmaker ASA @U1 base (110 → 100)
- Fiberon ASA-CF08 @Snapmaker U1 base (105 → 100)
- Fiberon PPS-GF20 @Snapmaker U1 base (105 → 100)
Bumps Snapmaker.json to 02.04.00.10.
Co-authored-by: yw4z <ywsyildiz@gmail.com>
--export-settings already writes the merged config as JSON at the right
point in the CLI flow. Passing - writes the same document to stdout.
- ConfigBase::save_to_json gains a stream overload. The file overload
serializes through it before opening the file, so the format is
unchanged and a config that cannot be serialized leaves an existing
file untouched instead of truncating it.
- On stdout, invalid UTF-8 in string values is written as U+FFFD instead
of ending the process with an uncaught type_error; files keep the
strict behaviour.
- - is rejected up front when combined with an action or transform that
can write to stdout or does real work, so stdout carries only the
JSON.
- The unconditional "skip locked instance" stdout write during arrange
now goes to the log.
- Tests in tests/libslic3r/test_config.cpp.
* Extract Layer::choose_ironing_extruder for unit-testable ironing routing
The ironing extruder selection in make_ironing() was a 5-line nested
conditional inlined at the top of the loop, with no isolated test
coverage. Pull the gating into a static helper so the routing decision
is unit-testable without spinning up the slicing pipeline.
Pure refactor: the helper preserves the original logic bit-for-bit
(NoIroning -> -1; AllSolid always enabled; TopSurfaces and TopmostOnly
require some top shells or, in spiral mode, more than one bottom shell;
TopmostOnly additionally requires being on the topmost layer; enabled
ironing routes to solid_infill_filament).
Add tests/fff_print/test_choose_ironing_extruder.cpp covering:
- AllSolid regardless of layer position
- TopSurfaces with top_shell_layers > 0
- TopSurfaces with top_shell_layers=0 + spiral mode + bottom_shell_layers>1
- TopmostOnly + topmost layer
- NoIroning short-circuit
- TopSurfaces with top_shell_layers=0 (and not spiral) -> disabled
- TopSurfaces, spiral, but bottom_shell_layers=1 -> disabled
- TopmostOnly on a non-topmost layer -> disabled
* Move ironing routing test into the Fill subsystem file
Rename the test to tests/libslic3r/test_fill.cpp and tag it [Fill] to
match the subsystem it covers, use flat behavioral test cases with
GENERATE for the parameterized ones, and drop the history narration from
the code comments.
* tests: move ironing routing tests into fff_print/test_fill.cpp
Keeps the Fill tests in one file, alongside the existing ironing
rotation-template test.
Cover the two cache paths the first test left open: a vendor tree that fails to load is retried on the next resolution instead of being served from the cache, and a type-probed filament resolved through resolve_preset_config_type reuses the OrcaFilamentLibrary base already loaded for a sibling.
Resolving a system preset through its vendor manifest loaded the whole vendor tree and the filament library from JSON, and the CLI did that separately for every --load-settings and --load-filaments file. A run with machine, process and filament presets parsed BBL's 2,879 profile files and the library's 512 three times over, about a second each.
Keep the library and vendor bundles loaded by the manifest path on the PresetBundle that resolved them, keyed by source root, vendor and substitution rule, and have the CLI resolve every system preset through one bundle for the whole run. A failed load is not kept, so errors are reported as before.
On a cube slice with X1C machine, process and PLA presets: 2.42 s -> 0.93 s, BBL.json opened once instead of three times, identical G-code.
The lift, speed and cached-extruder members now live in the protected section ahead of the private ones; list their initializers first so the list reads in construction order. No behaviour change.
BeltGCode is only created for belt printers, so its hooks no longer re-check belt_printer, and the BBL-machine flag is set once on whichever writer survives init_belt_writer instead of on one about to be discarded.
The bed gravity arrow, volume rendering and the painter/support gizmos each rebuilt
the tilt up-vector from build_plate_tilt_x/y; use one helper that also tolerates
presets without the keys.
Print::has_wipe_tower() is always false for belt printers, but CLI arrange, plate checks and the pre-slice tower clamp still reserved a phantom tower footprint and wrote a clamped wipe_tower_x/y into the config.
Extension layers were all created with id 0, so every one of them could be taken for the first layer by id-only checks (ooze-prevention standby temperature, cached layer ids). Renumber the support layers after inserting them.
gcode_back_transform, first_layer_plane* and belt_printer_infinite_y fell through to invalidate_all_steps(), which re-ran tool ordering, skirt/brim and G-code export on toggles that only affect G-code export.
Apron-only layers printed every band with the first tool, so objects with different brim filaments at the same apron Z shared one filament. Emit each brim filament's bands with its own toolchange.
The ordinary-layer path kept its own copy of the apron band loop. Give emit_belt_brim_bands() an optional brim filament filter and call it from the per-extruder lambda; without a filter it still prints every band, so apron-only layers are unchanged.
toggle_options() now runs on every value change and mode switch; rebuild the
brim_type choices only when the leading-edge entry has to be added or removed.
Every printer's config block lists belt_slice_rotation_angle (default 45), so the processor marked all G-code as belt G-code: imported flat G-code got the belt view on a belt printer, and the belt-only Z handling in the processor ran for non-belt prints whose config block precedes the body. Take the angle only from outside the config block, where only the belt header writes it.
A 90 degree tilt has no finite gravity drift per layer, so the option range
now stops at 89 degrees, matching the cap applied by the support generators.
The three support generators each computed lh * tan(tilt), which overflows
coord_t at 90 degrees and flips sign beyond it (belt sync can write up to
180). One helper now returns the tilt slope with the tilt capped at 89 degrees.
Painted support/seam facets, support volumes, seam occlusion, MMU and fuzzy skin painting (top/bottom
and side facets) and the adaptive infill octree used trafo_centered(), or trafo() with a centre-offset
shift, while the layers were sliced with the belt rotation, remap and Z lift; they now share
PrintObject::trafo_sliced().
The belt writer replaced the plate-offset-carrying writer mid-export, so belt G-code for any plate but the first kept the plate origin and long-travel clipping used the wrong frame. GCode now remembers the offset and hands it to the new writer, and the writer's first-layer probes use the plate-local point it emits.
build_plate_tilt_x/y are printer-preset keys; listing them in the per-object
frequent-settings and object-table bundles stored ignored values in object
configs and crashed the object table on the process config lookup.
Merge origin/main (00429da739) into belt-printer.
Conflicts resolved:
- src/CMakeLists.txt: keep both wxInspector workarounds.
- GCodeProcessor.cpp: keep the belt compare_pos / z_for_height lines.
- PrintObjectSlice.cpp: the belt bbox-Z guard also covers main's
printable_region_ids bookkeeping.
- TreeSupport.cpp: the belt-floor check runs before main's PendingNode
queueing.
- Tab.hpp: keep the belt fields, drop the removed upload description
fields.
- tests/libslic3r/CMakeLists.txt: keep both test files.
Also included:
- eSUN PLA belt presets declare their own filament_id (OFkrxQC4) and
scripts/filament_id_snapshot.json is regenerated, as main's filament_id
check requires.
- Custom.json version bumped to 02.04.00.05 so the belt entries reach
existing installs.
- Fix the ambiguous WithinRel call in the belt apron width test, which
otherwise breaks the fff_print build.
A valid mixed filament already slices the same on the CLI as in the GUI;
these are the places where the CLI still skipped a rule the GUI applies.
- Keep the prime tower when a mixed filament is used, even if every
--load-filaments preset is the same. A mixed filament swaps between its
components every layer, so turning the tower off left the swaps with
nothing to purge on.
- Leave a mixed slot's row and column of the flush matrix at zero when
--filament-colour triggers a recompute, as the GUI does; a mixed slot
never reaches a nozzle.
- Refuse a mixed slot that has no filament of its own. Feature filament
ids aimed at it were past the filament count, got reset to filament 1
and the model silently printed in one colour.
- Refuse a plate that uses a mixed filament whose components are
different filament types, the type half of the GUI's
Sidebar::has_broken_mixed_filament. Missing or out-of-range components
are already rejected for the whole project by validate().
get_extruders_under_cli gains an expand_mixed_slots flag so the gate
can see mixed slots rather than their components; existing callers
keep the expanded list.
Both refusals exit with the new CLI_MIXED_FILAMENT_INVALID (-69).
update_values_to_printer_extruders_for_multiple_filaments picks each
filament's value from the flattened (filament x variant) columns of every
per-filament variant option. When a column index fell past the end of the
option's values, it skipped that filament and left the zero the output
vector was created with.
The GUI always hands this function full columns, but the CLI does not:
- a CLI override of a single value, such as --nozzle-temperature=211 on a
four-filament project, came out as 211,0,0,0, so three filaments would
print at 0 C;
- loading fewer filament presets than the project has filaments left the
remaining filaments' columns missing, so filament_cooling_before_tower
came out as 10,10,0,0 and filament_ramming_volumetric_speed as -1,-1,0,0.
An out-of-range column now keeps the option's first value, the fallback
get_at() and the sibling gather step already use. The seven per-type copies
of the loop are replaced by that same gather_option_values helper, moved
above the function; it now takes its caller's name for its log lines. An
empty option, which has no first value, is given one registered default per
filament first; it used to be replaced with zeros.
On a partial load a filament whose preset was not loaded takes the first
filament's value rather than its own preset's, which the CLI does not load;
for the options seen in practice those agree.
Runs orca-test-repo's full override-sweep effect stage (two shards) and the GUI-vs-CLI parity harness every night against the latest successful build_all Linux AppImage, with sources checked out at that build's commit. Kept out of the per-build regression step, whose time budget it would exceed, and never gates a build.
# Description
<!--
> Please provide a summary of the changes made in this PR. Include
details such as:
> * What issue does this PR address or fix?
> * What new features or enhancements does this PR introduce?
> * Are there any breaking changes or dependencies that need to be
considered?
-->
Adds a really basic API to push notifications to the plater.
Plugin used in demo:
[plater_notification.py](https://github.com/user-attachments/files/31293074/plater_notification.py)
# Screenshots/Recordings/Graphs
<!--
> Please attach relevant screenshots to showcase the UI changes.
> Please attach images that can help explain the changes.
-->
<img width="2172" height="1241" alt="image"
src="https://github.com/user-attachments/assets/540319ca-a11a-4b48-9b80-82fb6b0849d9"
/>
## Tests
<!--
> Please describe the tests that you have conducted to verify the
changes made in this PR.
-->
<!--
> A guide for users on how to download the artifacts from this PR.
-->
[How to Download Pull Requests Artifacts for
Testing](https://www.orcaslicer.com/wiki/how_to_download_pr_artifacts)
* CLI: record command-line overrides in different_settings_to_system
Settings passed on the command line (--sparse-infill-density 25% ...) override
the loaded presets when m_extra_config is applied to m_print_config, but nothing
recorded them in different_settings_to_system. The exported project therefore
carried the new value with no mark that it was modified, and re-opening it in the
GUI reverted it to the system preset's value -- the same failure the preset-leaf
diff fixes for user presets, via a different source of override.
The key set comes from m_config, not m_extra_config. read_cli() puts only what the
user typed into m_config and setup() adds nothing but CLI-own defaults (none of
the keys run() materialises there is a preset option), whereas the CLI writes its
own values into m_extra_config (has_filament_switcher, filament_colour,
filament_map ...), which must not be reported as user overrides.
Values are snapshotted just before the apply and only keys the override actually
changed are recorded: a typed value equal to the loaded one modifies nothing, and
listing it would read as a spurious difference against what the GUI writes. Each
key lands in the column(s) whose preset type owns it -- process, every filament,
printer -- and a key already present is not duplicated. Keys no preset owns
(curr_bed_type, a project setting) land nowhere, as in the GUI.
Follow-up to #15595, split out at review.
* CLI: judge command-line overrides the way the value is read
Review follow-ups on the override recording:
- Lists were compared as whole serialized strings. read_cli() builds a fresh
one-entry list, so --nozzle-temperature 245 against 245,245,245 on a
three-filament project was recorded in every filament column although nothing
changed. Lists are now compared entry by entry with a missing entry read as the
first, as get_at() reads it (and as resize() pads).
- The log line fired for every changed key, including ones no preset owns
(curr_bed_type) and which therefore land in no column. It now fires only when a
column took the key.
- m_print_config.has(key) straight after apply(m_extra_config, true) was always
true, both configs sharing print_config_def; removed. columns.size() >= 2 also
always holds after the resize to filament_count + 2 -- different_settings_to_system
is not a CLI option, so nothing in between can shrink it -- but that rests on code
far away, so it stays a plain check rather than an assert: release builds compile
asserts out, and a _GLIBCXX_ASSERTIONS build would abort on columns[0].
Deliberately NOT done: comparing a key the loaded config lacks against its
built-in default. On reopen the GUI restores an unlisted key from the SYSTEM
preset, not the default. A 3MF written before an option existed leaves it absent
here, so --sparse-infill-density 20% (the default) against a Prusa system 15% would
go unrecorded and be reverted to 15%. Absent keys stay always-recorded:
over-recording is cosmetic, under-recording loses the value. Verified that such a
key really is absent at this point, rather than filled from the system preset.
Reported by HanifKoh and raistlin7447 in review of #15642.