Ooze prevention currently treats every toolchange as a transition between
independent hotends — the OLD filament's extruder cools to a standby
temperature (via standby_temperature_delta or the filament's
idle_temperature) before the change, and the NEW filament's extruder
ramps back up afterward. This is correct for IDEX/toolchanger setups
where the parked nozzle would drip otherwise.
For AFC/MMU lane swaps where the SAME physical extruder stays selected
(only the loaded filament changes), the cool-down → re-heat round trip
is pointless: same nozzle, same heater, just a different filament feeding
it. In-print this costs 30+ seconds per lane swap, and the AFC tip-form
sequence ends up running on a cooling extruder.
Gate the pre_toolchange call on physical_extruder_map: when both the old
and new filament index map to the same physical extruder, skip the
standby cool-down. post_toolchange is left untouched — its M109 to the
new filament's print temp is still emitted, so per-lane temperature
differences (e.g. PLA → PETG on the same AFC manifold) are still handled.
Note on pem sizing: the guard requires physical_extruder_map to be sized
to the filament count for the per-filament lookup to succeed. The option's
registered default is a single-entry [0], which is shorter than the filament
count on any multi-filament setup, so the bounds check fails and ooze runs
as before. The fix fires only on profiles that explicitly author pem to
match filament count (the AFC/MMU/toolchanger configs that actually encode
same-physical routing).
Behavior matrix:
| Config | pem | Ooze behavior |
|---|---|---|
| Single-extruder + SEMM | (any) | `init_ooze_prevention` already disables ooze. No change. |
| Single-extruder, no SEMM | (any) | Single filament, no toolchanges. N/A. |
| IDEX / Toolchanger | `[0,1,…]` per-filament | Cross-physical → ooze runs as before. |
| Vanilla AFC, SEMM=true | (any) | `init_ooze_prevention` disables ooze. No change. |
| Vanilla AFC, SEMM=false | `[0,0,…]` per-filament | Same physical → **ooze SKIPPED** (the fix). |
| Toolchanger + AFC | per-filament | AFC swaps skip, cross-physical swaps run. |
| Default pem `[0]` (1 entry) | shorter than filament count | Bounds check fails for filament index ≥ 1 → ooze runs as before. No-op for profiles that haven't authored a per-filament pem. |
| Empty pem | `[]` | Guard returns false → ooze runs as before. |
The guard depends only on physical_extruder_map; no machine-class check.
Any printer whose pem is sized to filament count and indicates multiple
logical slots routed to the same physical hotend benefits.
The firmware-managed-zones writer offset puts prim_pos and the preview
toolpaths in a frame shifted relative to the bed bounds the zone math
uses, so secondaries would have rendered off the plate. Skipping the
secondary computation when firmware-managed is on keeps the centered
preview honest.
Addresses Felix14-v2 feedback on PR #13086.
124 upstream commits including CrealityPrint integration (added include
in Plater.cpp alongside the existing IMEXHelpers include), profile fixes
and version bumps (#14084, #14085, Polymaker), CI artifact publishing,
test refactors (arachne walls test added; test_3mf/test_config/
test_gcodewriter content moved/removed upstream — IMEX test file
preserved as it is feedback-only), translations.
The firmware-managed-zones writer offset centers the slice at bed origin,
so prim_pos and the preview toolpaths sit in a shifted frame relative to
the plate-local bed bounds the secondary-marker zone math uses. Computing
secondaries against unshifted bed bounds puts them off the build plate.
Skip the secondary-marker / toolhead-box computation when the
firmware-managed-zones option is enabled. The firmware physically fans the
centered toolpath out into the zones at print time, so the honest preview
is the single centered toolpath with no secondaries.
Reported by @Felix14-v2 on PR #13086.
## Summary
Adds end-to-end Creality K-series (K2 / K2 Plus / K2 Pro) host support
to OrcaSlicer in a single bundle, per [@SoftFever's request to
consolidate](https://github.com/OrcaSlicer/OrcaSlicer/pull/13752#issuecomment-4560837450)
the previously stacked PRs. Three logically separable features, all
gated on `host_type=crealityprint`:
1. **LAN auto-discovery** — `Browse...` in the Physical Printer dialog
now finds K-series printers on the local network via a DNS-SD
meta-browser (per-device-unique service names
`_Creality-<MAC>._udp.local.`). Other host types unchanged.
2. **CFS filament sync** — `CrealityPrintAgent` (inheriting
`MoonrakerPrinterAgent`) queries the K-series WebSocket on `:9999` for
`boxsInfo`, maps loaded CFS slots to Orca filament presets, and
populates the Sidebar via the standard `fetch_filament_info` →
`build_ams_payload` path. Matches the shape of `MoonrakerPrinterAgent` /
`QidiPrinterAgent` / `SnapmakerPrinterAgent` per [the earlier review
feedback](https://github.com/OrcaSlicer/OrcaSlicer/pull/13752#discussion_r3278574545).
3. **K-series filament profiles** — system profiles for CR-PLA / CR-PETG
/ CR-ABS / CR-Silk / CR-TPU / CR-Nylon / CR-Wood / Hyper PLA / etc. on
K2 / K2 Plus / K2 Pro nozzle sizes (imported from CrealityPrint v7.1.0+,
normalised to OrcaSlicer profile conventions).
The previous stack base (#13291, *CrealityPrint as host type*, by
@imammedo) is **also bundled into this PR** since it's currently
conflicting with main and not moving. Happy to extract it back out if
@imammedo's PR is preferred to land first for attribution — let me know.
## What this PR is *not*
- **No new UI surfaces.** All three features hook into existing UI
(Browse button, Sidebar sync icon, filament dropdowns).
- **No phone-home / telemetry.** No Hark Tech endpoints, no licence
checks, no opt-in dialogs. Pure upstream feature work.
- **No K-series-specific Device tab.** Embedded WebView falls back to
Fluidd/Mainsail on `:4408`, same shape as the existing Moonraker
integration.
## Screenshots
Captured against a K2 Combo (F021, firmware v1.1.260206) on the v4 test
build:
| | |
|---|---|
| 
| **Discovery dialog** — `Browse...` flow on a `host_type=crealityprint`
printer. Click → ~5–10 s LAN scan → K2 found with model + hostname + IP.
|
| 
| **CFS filament sync** — Sidebar after clicking the sync icon: 4 slots
populate with the real loaded CFS spools (3× Hyper PLA + 1× CR-Silk). |
| 
| **Device tab** — Mainsail loaded into the embedded WebView for
`host_type=crealityprint`, mid-print state visible. |
## What's added
### LAN discovery
- **`deps_src/mdns/`** — vendors
[mjansson/mdns](https://github.com/mjansson/mdns) (public domain) plus
Creality's `cxmdns` C++ wrapper from CrealityPrint v7.1.1 (AGPL-3.0,
compatible with OrcaSlicer's AGPL-3.0). Attribution in
`deps_src/mdns/NOTICE.md`.
- **`Utils/CrealityHostDiscovery.{hpp,cpp}`** — synchronous DNS-SD scan
+ per-host `GET /info` probe. Maps model codes `F008` / `F012` / `F021`
→ K2 Plus / K2 Pro / K2.
- **`GUI/CrealityDiscoveryDialog.{hpp,cpp}`** — modal `wxDialog` showing
Model / Hostname / IP for each discovered host.
- **`src/slic3r/CMakeLists.txt`** — adds `Iphlpapi.lib` and `Ws2_32.lib`
to `libslic3r_gui`'s MSVC link line (needed by `GetAdaptersAddresses` +
Winsock2 calls in vendored `mdns.c`).
### CFS filament sync
- **`Utils/CrealityPrintAgent.{hpp,cpp}`** — inherits
`MoonrakerPrinterAgent`, overrides `fetch_filament_info()` to query the
K-series WS protocol on `:9999`, build `AmsTrayData`, and call inherited
`build_ams_payload()`. No printer-specific code lives outside the agent.
- K2 Plus slot-state parser handles the three documented slot states
(`0` empty / `1` manually entered / `2` RFID-tagged) per [DaviBe92's
reverse-engineering docs](https://github.com/DaviBe92/k2-websocket-re).
### K-series filament profiles
- ~110 profile JSONs under `resources/profiles/Creality/filament/`
covering K2 / K2 Plus / K2 Pro × 0.2 / 0.4 / 0.6 / 0.8 nozzle combos ×
CR-PLA / CR-PETG / CR-ABS / CR-Silk / CR-TPU / CR-Nylon / CR-Wood /
Hyper PLA / Hyper PETG-GF / Hyper PLA-CF / etc.
- Imported from CrealityPrint v7.1.0; normalised to OrcaSlicer profile
conventions (tabs not spaces, no `{if !multicolor_method}` wrappers,
`filament_vendor: ["Creality"]` on Creality Generic profiles).
## Tester confirmations on the v4 test build
| Printer | Firmware | Result | Reporter |
|---|---|---|---|
| K2 Pro | v1.1.5.5 / CFS v1.4.2 | ✅ LAN discovery on #13752 test build
|
[@Requiem-MH](https://github.com/OrcaSlicer/OrcaSlicer/pull/13752#issuecomment-4495235225)
|
| K2 Pro | v1.1.5.5 / CFS v1.4.2 | ✅ CFS sync across 1-CFS, 2-CFS,
partial, full configurations |
[@Requiem-MH](https://github.com/OrcaSlicer/OrcaSlicer/pull/13744#issuecomment-4495230061)
|
| K2 Plus | v1.1.5.2 / CFS v1.2.2 | ✅ Slot-state fix resolves the
partial-sync regression |
[@DaviBe92](https://github.com/OrcaSlicer/OrcaSlicer/pull/13744#issuecomment-4499425852)
|
| K2 Plus | v1.1.5.5 / CFS v1.4.2 | ✅ All slots syncing correctly after
fix |
[@swilsonnc](https://github.com/OrcaSlicer/OrcaSlicer/pull/13744#issuecomment-4503273127)
|
| K2 Plus | (Reddit u/TrainAss) | ✅ Both PLA + PETG slots populated
correctly |
[@TrainAss](https://github.com/OrcaSlicer/OrcaSlicer/pull/13744#issuecomment-4503401664)
|
| K1C | (latest stock) | ✅ `boxsInfo` payload format compatible (4 slots
of generic PETG) |
[@JoveYu](https://github.com/OrcaSlicer/OrcaSlicer/pull/13744#issuecomment-4519036448)
|
## Known follow-ups (out of scope)
- **Snapmaker U1 regression**
([@TrainAss](https://github.com/OrcaSlicer/OrcaSlicer/pull/13744#issuecomment-4529350262)):
the v3 build also happened to sync filament from his U1; v4 regressed
this. The refactor only touches `htCrealityPrint`-gated code so this is
likely incidental — needs his config + logs to diagnose. Will follow up
in a separate issue once this lands.
- **Native Device tab for K-series**: deferred. Current Mainsail WebView
shim covers the common case.
- **#13581 (@hamham999) profile overlap**: confirmed minimal code
conflict (zero), profile-file overlap of ~204 files. Whichever PR lands
second rebases off the other.
## Test plan
- [x] Linux build clean on commit `<UPDATED AFTER BUILD>` (LXC 104, GCC
12, cmake)
- [x] MSVC link clean (manual VS 2026 / MSVC 14.51 build)
- [x] End-to-end on real hardware: K2 Combo, K2 Pro, K2 Plus, K1C
- [x] `host_type ≠ htCrealityPrint` paths unchanged — Bonjour fires for
OctoPrint, Flashforge picker fires for Flashforge, Moonraker / Qidi /
Snapmaker agents unchanged
- [x] Profile-validation CI green (was a separate Elegoo test-fixture
failure on main, not introduced by this PR)
Signed-off-by: Igor Mammedov <niallain@gmail.com>
Co-authored-by: Igor Mammedov <niallain@gmail.com>
Co-authored-by: grant0013 <grant@harktech.co.uk>
Co-authored-by: SoftFever <softfeverever@gmail.com>
Co-authored-by: hamham999 <hamham999@users.noreply.github.com>
Co-authored-by: Alys Andreollo <3528187+alysandreollo@users.noreply.github.com>
The SPARKX i7 machine presets shipped (via #13947) with a contributor's
LAN IP (http://10.10.1.39) hardcoded in print_host. Remove it to match
the K2/K2 Pro/K2 Plus presets, which carry no print_host key — LAN
discovery + the crealityprint agent populate the host at add-printer time.
This updates the SPARKX i7 from a "regular" klipper printer to use the
new CrealityPrinter agent, that talks to it's "supervisor" webserver
instead, and can use the native Creality features: CFS, filament
querying, filament remapping, etc...
* init
* update translations
* clarify warning for rebuild
* auto fill issue field on github with gathered system information
* add detection for linux package type
* fix build errors
* update
* update
* improve reading windows version
* add multi file support for zip and use timestamp on exported zip name
* fix errors
* fix errorz
* fix URL encoding
* fix CPU info
* use home or desktop as default location
* fix distro name on flatpak
* improve detecting local build on linux
* check package type on all platforms
* optimize margins
* improve monitor detection
* add support for adding text file to zip and add system info on export
* exclude user related info from config
* improve exporting profile info
* fix linux monitor info
* update
* update detecting monitor info
* Update TroubleshootDialog.cpp
* Update TroubleshootDialog.cpp
* Update TroubleshootDialog.cpp
* revert scaling and resolution detection for linux
* include project file to zip and notify after saving zip successfully saved
* improve monitor info on mac
* update
* improve packing selection menu
* update
* Update TroubleshootDialog.cpp
* Update TroubleshootDialog.cpp
* Update TroubleshootDialog.cpp
* Update TroubleshootDialog.cpp
* update
* update
* make hash clickable
* fix compatible process counting
* export profiles overview instead copying to clipboard
* auto restart app after cleaning system folder
---------
Co-authored-by: Noisyfox <timemanager.rick@gmail.com>
ws2_32 (Winsock2) and wsock32 (Winsock) are not supposed to be used in the same application.
boost::asio requires ws2_32, but wxWidgets uses wsock32.
Which gets used depends on the order they appear in the link command, as they both define the same symbols, but with different behaviour.
ws2_32 is backwards-compatible with wsock32, so wxWidgets won't be negatively affected by linking with the newer version, and prior to c228ab2da1, that's what happened.
That commit reordered how some libraries were passed to the linker, so swapped the order of these two, breaking mDNS and causing https://github.com/OrcaSlicer/OrcaSlicer/issues/13969
The CFS-aware filament sync resolves its agent via switch_printer_agent(),
which reads the preset's `printer_agent` field and falls back to "orca" when
unset -- so the K-series presets need printer_agent="crealityprint" (the id
registered by CrealityPrintAgent) in addition to host_type="crealityprint"
(classic PrintHost/LAN-discovery). Without printer_agent the Device-tab sync
defaults to the Orca agent and CFS sync doesn't engage. Set both on the
F008/F012/F021 models that supports_multi_color_print() covers (not K2 SE).
Both keys are in s_PhysicalPrinter_opts, so a new Physical Printer inherits
them from the preset.
* Add test for Arachne duplicate wall segment detection
Add test cases that reproduce an issue where Arachne generates
duplicate/coinciding extrusion segments at certain min_bead_width settings.
Test configuration:
- Profile: 0.28mm Extra Draft @BBL X1C (0.4mm nozzle, 0.28mm layer)
- outer_wall_line_width: 0.42mm, inner_wall_line_width: 0.45mm
- wall_loops: 2, precise_outer_wall: enabled
- Test polygon: outer rectangle (0,0)-(20,20) with inner cutout (0.5,0.5)-(19.5,19.5)
This creates a 0.5mm wide frame around the perimeter.
Results:
- 50% min_bead_width (0.20mm): FAILS - detects 4 duplicate segments (all 4 sides)
- 60% min_bead_width (0.24mm): PASSES - no duplicates
At 50%, Arachne generates two separate closed loops that share all 4 edges
of the inner square. At 60%, Arachne generates a single closed loop.
SVG output is exported to /tmp/opencode/ for visual debugging.
* Fix Arachne duplicate extrusion caused by bead count mismatch
WideningBeadingStrategy::compute() used optimal_width (inner wall width)
to determine if a thin wall should produce a single bead. However,
getOptimalBeadCount() uses optimal_width_outer (outer wall width) via
RedistributeBeadingStrategy to decide the bead count.
This inconsistency caused situations where getOptimalBeadCount() returned
2 beads, but compute() produced only 1 bead at full thickness. The single
bead was then generated for both inner and outer contours, resulting in
duplicate extrusion paths.
Fix: Use getTransitionThickness(1) instead of optimal_width. This method
returns the exact threshold for the 1-to-2 bead transition, ensuring
consistency between bead count calculation and bead generation.
Reproduces with: 50% min_bead_width, 0.42mm outer wall, 0.45mm inner wall,
0.5mm polygon inset creating ~0.38mm wall thickness.
Fixes#13917
---------
Co-authored-by: SoftFever <softfeverever@gmail.com>
* Linux compositing - retain old code and make switchable via #if statement
* Make option settable via env variable/.desktop file
* undo accidental empty row delete
Made small performance, safety, and readability improvements.
Now the logic is only called to move the build plate lower than the tallest object if the print_sequence is, "by object".
More precise checks to not move the plate beyond the maximum build volume.
OrcaSlicer currently ships an "Octo/Klipper" host type that maps to the
OctoPrint REST endpoints (api/version, api/files/local). It works for
Klipper setups that run Moonraker with the OctoPrint-emulation plugin,
but native Moonraker — and Moonraker-compatible firmwares like the
Prusa-Firmware-Buddy buddy-klipper fork — speak a different shape:
distinct paths, JSON body for /printer/print/start, {"result":...}
envelope. There's no host type for that today.
Add a new Moonraker class deriving from PrintHost. Endpoints used,
matching the Moonraker spec:
- GET /server/info — connection test, reads
result.klippy_state
- GET /server/files/roots — storage-picker dropdown
(returns roots with 'w'
permission); gracefully
degrades if absent
- POST /server/files/upload (multipart) — upload (form fields:
file, root)
- POST /printer/print/start (json) — {"filename":"<path>"}; the
filename is whatever the
upload response returned
in result.item.path, so any
server-side rename
(collision suffix etc.) is
respected. JSON body is
built via property_tree
write_json so exotic
characters in the path are
properly escaped.
Auth: X-Api-Key header, only when printhost_apikey is non-empty
(Moonraker can be configured to require it but doesn't by default).
HTTP Basic / Digest are not part of the Moonraker spec and are not
sent.
Storage root is read from upload_data.storage with "gcodes" as the
fallback default, so the existing storage-picker plumbing in
PrintHostDialogs lights up automatically once enumerable roots are
returned.
UI: registers as the "Moonraker (Klipper)" entry under host_type;
selectable via the existing Physical Printer dialog (sidebar's
connection button on the printer card).
Verified against a Prusa-Firmware-Buddy buddy-klipper fork (firmware
identifies as moonraker_version "0.8.0-prusalink-shim"): /server/info
test, multipart upload to /server/files/upload, and JSON
/printer/print/start all work end-to-end. The existing "Octo/Klipper"
entry is left untouched so users currently relying on Moonraker's
OctoPrint-emulation plugin keep working.