Commit Graph
1095 Commits
Author SHA1 Message Date
SoftFever b663f851fe Merge branch 'main' into feat/plugin-feature 2026-07-17 11:30:34 +08:00
Mqrius 6d1974a662 Restore flow calibration special order, overridable via fill order (#14786) 2026-07-16 09:10:15 -03:00
Noisyfoxandjun.zhang 5e7ad1ad70 Fix OpenGL framebuffer object support on macOS (#14769)
* Fix OpenGL framebuffer object support on macOS
this enables the outline on macOS

* Revert "Fix OpenGL framebuffer object support on macOS"

This reverts commit 9872708954e785a86209613bbab7cc770d636b7a.

* Enable ARB framebuffer if OpenGL >= 3.0 (OrcaSlicer/OrcaSlicer#14770)

* FIX: plater toolbar image update

jira: STUDIO-12457

Change-Id: Ia855b4bd9bec884d52202f5d8f5cfad9efce0f2f
(cherry picked from commit 474691813b497654ef701fe7073992db366e81a9)

* FIX: thumbinal regen

jira: STUDIO-16732

Change-Id: I4cc4e76b36caf1a41793c1f84ee5e88a44ebdd42
(cherry picked from commit 53f33b7db260005e477842d6459b1b28aa8aa0d8)

* FIX: force update thumbinal once dirty

jira: STUDIO-13041

Change-Id: I770743b53c51351cb3b8a7133140974c75c05364
(cherry picked from commit 96198a12712f21d2b4521b6e3d1caff50bed21ff)

* FIX:thumbnail update

jira: STUDIO-13041 / STUDIO-13304

Change-Id: I9dec25f12454fc8485195cf5dc3feb421b6347c4
(cherry picked from commit cf778dc90f805d3f46e28f8f1d1d5814d3fb4d51)

---------

Co-authored-by: jun.zhang <jun.zhang@bambulab.com>
2026-07-16 11:02:55 +08:00
Ian Chua 8ba478913f fix merge conflicts 2026-07-15 22:09:47 +08:00
SoftFever 1551898846 Plugin-gate the reslice check and drop non-plugin leftovers
reslice() now enforces only the missing-plugin block via
refresh_missing_plugin_block (no second Print::validate); plate
ready-status returns to upstream's plain model_fits, matching
GLCanvas3D::reload_scene. Also restores main's use_bbl_device_tab and
the check_track_enable comment, and drops two unused MainFrame includes.
2026-07-15 19:18:45 +08:00
SoftFever 8cb0cb7693 Merge branch 'main' into feat/plugin-feature
Resolve five conflicts, all of which needed both sides rather than a pick:

- BackgroundSlicingProcess: ours was a pure tabs->spaces reformat of base, so
  keep main's per-filament volume/nozzle map read-back (its only change here).
- GUI_App: main's #12506 else-if attached to an `if` this branch deleted;
  re-expressed onto the same-agent early-return path (the agent factory caches
  per id, so pointer equality is the same predicate).
- MainFrame: both sides relocated Sync Presets independently; keep main's
  push_notification plus the branch's Plugins menu items.
- Tab: the "TODO: Orca: Support hybrid" blocks were unchanged base, not a branch
  decision; take main's enabled Hybrid to match the already auto-merged siblings.
- test_config: union of both sides' cases (6 plugin + 9 multi-nozzle).
2026-07-15 17:18:46 +08:00
MqriusandIan Bassi c84d5c7943 Add top/bottom surface fill order control (Outward/Inward) for Concentric, Archimedean Chords and Octagram Spiral (#14179)
Co-authored-by: Ian Bassi <ian.bassi@outlook.com>
2026-07-14 15:34:13 -03:00
SoftFever 74813b401f Merge remote-tracking branch 'origin/main' into feature/h2c_support_clean
# Conflicts:
#	localization/i18n/fr/OrcaSlicer_fr.po
#	localization/i18n/list.txt
2026-07-14 02:54:20 +08:00
foXaCe c41e685a69 i18n: wrap hardcoded GUI strings (undo/redo labels, dialogs, notifications) + FR (#14729) 2026-07-13 12:19:33 -03:00
Noisyfox 64a321528d Fix issue that unable to open 3mf again once the 3mf action dialog is cancelled (#14715) 2026-07-13 14:40:24 +08:00
Noisyfox 6a254c35d4 Make printer profile swithing faster (#14437)
* Fix issue that switching printer profile is slow.
`wxGetApp().get_tab(preset_type)->select_preset(preset_name);` is called twice when switching printer profiles. Only one needed.

* Avoid unnecessary type conversion & function call during printer profile switching:
- Don't call `config->opt_string("printer_model")` repeatedly
- Use ref when possible during iterating
- Avoid unnecessary `wxString` to `std::string` conversion
2026-07-13 09:52:18 +08:00
Rodrigo Faselli 79aa0bd4a2 Merge branch 'main' into feature/h2c_support_clean 2026-07-12 22:00:40 -03:00
yw4z e1c0ea0cc4 UI fixes & improvements (#14186)
* titlebar menus

* sidebar separators

* Update BonjourDialog.cpp

* Update StepMeshDialog.cpp

* Z contouring icon

* Update AmsMappingPopup.cpp

* Update AmsMappingPopup.cpp

* sync ams dialog

* Update calib_dlg.cpp

* sync popups

* Update AmsMappingPopup.cpp

* operation section on gizmos

* Update PresetComboBoxes.cpp

* Update GCodeViewer.cpp

* Update GCodeViewer.cpp

* Update AboutDialog.cpp

* disable realistic view option on gcode preview

* Update Preferences.cpp

* fix nozzle text clipping on linux
2026-07-11 20:24:03 +03:00
SoftFever f5418415ac fix(gui): stop clipping the nozzle-count edit button on flow changes
HoverLabel's constructor used SetSizerAndFit, which records the
count-hidden width as the panel's explicit minimum size. An explicit
minimum outranks best size in sizer allocation, so once the "(N)" count
was shown, any ancestor Layout() - e.g. switching the extruder flow type
to Standard or High Flow - shrank the title row back to the stale width
and clipped the trailing edit button. Hybrid only appeared correct while
nothing had re-laid the row since its own Fit().

Use plain SetSizer and, on every title/count change, invalidate the
cached best size and re-lay both the row and its parent so the sizer
always allocates the current content width.
2026-07-11 22:11:47 +08:00
SoftFever 75c8d0775a feat(gui): per-filament nozzle volume selection and persistence
- FilamentMapDialog's manual page understands volume types: a mixed
  (Hybrid) extruder shows separate Standard / High Flow drop zones
  with live sub-nozzle counts, a validation timer with an inline
  error + "set nozzle count" suggestion, and composes a per-filament
  volume map on OK (persisted to the plate or globally)
- switching an extruder's Flow type rewrites the affected plate map
  entries; plate maps stay sized across filament add/delete/count
  changes (values keep their filament, no index shift)
- CLI: manual mapping on multi-nozzle printers synthesizes the volume
  map from extruder flow types when absent; nozzle-manual mode
  requires explicit maps; computed maps land on the plate so exported
  projects carry filament_volume_maps
- filament_nozzle_map joins the project options (selection seeding +
  filament-count resizing)
- pot entries for the new dialog strings

All 19 reference fixtures byte-identical; slicing an exported Hybrid
project reproduces its g-code byte-for-byte with the volume map
round-tripped through model_settings.config.
2026-07-11 16:37:50 +08:00
SoftFever 03a704df7c feat(engine): wire the per-filament volume-map producer pipeline
- Print::update_filament_maps_to_config takes filament/volume/nozzle
  maps, backfills an empty volume map from extruder types, rebuilds
  filament_map_2, re-expands the per-filament variant arrays, and
  recomputes retract overrides keyed by resolved slots
- grouping writes its result back in every non-sequential mode;
  manual multi-nozzle grouping validates the user mapping and raises a
  translatable error on deviation; the engine's concrete volume
  assignment is deliberately not merged yet (per-filament arrays are
  already consumed by filament id, so materializing High Flow now
  would change motion before the layer-aware resolvers land)
- Print::apply treats the three map keys as engine outputs in auto
  modes (erased from the diff and adopted), compares them against used
  filaments in manual mode, and keeps the pre-expansion snapshot in
  sync with the late normalization pass so rebuilt headers reflect the
  sliced state instead of resurrecting stale values
- volume/nozzle maps and extruder_nozzle_stats join the invalidation
  group of filament_map (wipe tower + skirt/brim)
- PresetBundle composes full configs with an optional per-filament
  volume map (plate map, else defaults derived from each extruder's
  flow type); project config keeps the map sized across filament
  count changes
- PartPlate stores per-plate volume/nozzle maps; Plater injects them
  at every slice-composition site (incl. g-code reload and wipe-tower
  estimation); BackgroundSlicingProcess reads engine results back to
  the plate in auto modes
- per-filament map trust guards relaxed to size-match everywhere now
  that every producer sizes the map; single-filament explicit flow
  assignments are honored
- tests: grouping volume maps stay concrete, merge semantics of
  update_used_filament_values, single-filament override honoring

Motion g-code is byte-identical fleet-wide including Hybrid projects
(19-fixture gate + repro determinism double-slice). Header deltas:
the map keys now dump real values, and stale pre-normalization values
(e.g. enable_prime_tower on single-used-filament prints) no longer
leak into the config block.
2026-07-11 04:38:31 +08:00
SoftFever 7c8d086d9e feat(gui): show per-extruder nozzle count with inline editor
The sidebar extruder cards get an interactive title row — "<name> ( <count> )"
with an edit button — showing the extruder's physical nozzle count on
multi-nozzle printers (hidden elsewhere). Clicking it opens the existing
"Set nozzle count" dialog, which now also handles a Hybrid extruder by
offering both Standard and High Flow counts (an empty mix is rejected) and
shows a hotend thumbnail.

Because `extruder_nozzle_stats` is session-only (saved presets never carry
it, so preset switches rebuild the edited config without it), the stats are
re-baselined whenever they are missing: each extruder starts with
extruder_max_nozzle_count nozzles of its selected volume type. Switching an
extruder's flow type carries its total count over to the new type, except
when the stats came from a device sync — the machine-reported per-type
breakdown must survive a manual flow switch.

The badge refreshes on preset load, flow-type change, manual edit, device
sync, and project load. Single-extruder cards keep the title row but never
enable editing.
2026-07-10 19:47:21 +08:00
SoftFever c528d3a0bc feat(gui): enable Hybrid nozzle flow for multi-sub-nozzle extruders
An extruder with more than one physical sub-nozzle can hold a mix of
Standard and High Flow nozzles. The Flow dropdown now offers Hybrid for
such extruders (extruder_max_nozzle_count > 1, nil-guarded); grouping
already expands a Hybrid extruder into per-volume nozzle groups from
extruder_nozzle_stats.

- sidebar Flow combo offers Hybrid only for multi-sub-nozzle extruders
- preset lookup treats Hybrid as Standard (presets define no Hybrid
  variant); variant strings are never fabricated for it
- printer tab splits a Hybrid extruder into Standard + High Flow rows,
  with matching selection-index arithmetic and sync-enable rules
- syncing from a printer whose extruder holds mixed nozzle flows now
  selects Hybrid instead of collapsing to the dominant flow type
- send-to-printer flow check: a nozzle-rack extruder validates its
  nozzle inventory (mounted + rack) against every needed flow instead
  of comparing only the mounted nozzle; mounted-flow lookup is now
  per-extruder, fixing an index shift when a nozzle reports no flow
- Hybrid is session-only in app config (stored as Standard), so a
  fresh session starts from concrete flow types

Printers whose extruders have a single sub-nozzle (including all
dual-extruder machines without a rack) see no new option and identical
check behavior.
2026-07-10 18:02:26 +08:00
SoftFever 93a81179a1 feat(gui): add purge mode selector dialog
The engine already implements prime_volume_mode (Default/Saving/Fast)
but nothing in the UI could set it, leaving prime-saving unreachable on
multi-sub-nozzle extruders and fast purge unreachable on printers that
support it.

- new PurgeModeDialog with selectable Standard/Fast or
  Standard/Prime Saving cards depending on printer capability
- "Purge mode" sidebar button next to Flushing volumes; opens the
  dialog and stores the choice in the project config
- printer preset-load gating: button shown only when the printer has
  multiple sub-nozzles per extruder or sets support_fast_purge_mode;
  stale project values the printer cannot honor reset to Default
- enable fast purge on A2L 0.4 (support_fast_purge_mode), explicit
  default 0 in the common machine base
- new dialog strings added to OrcaSlicer.pot

Printers without these capabilities never show the button and their
projects keep prime_volume_mode at Default, so slicing output is
unchanged.
2026-07-10 15:41:57 +08:00
SoftFever 00816968a2 Merge branch 'main' into feature/h2c_support_clean 2026-07-09 22:17:20 +08:00
SoftFever 0d31325df0 feat: Filament Track Switch (H2-series O2L-FTS) support
The Filament Track Switch (H2-series accessory, product code O2L-FTS) feeds
every AMS to both extruders through a two-track switch. Port full support
across the device layer, project config, and GUI.

Device / config:
- Model the switch-aware AMS binding (the set of extruders an AMS can feed
  and which input track A/B feeds it), switch readiness, the O2L-FTS firmware
  module, and the fun2 capability bit for checking a slice against installed
  hardware.
- Register has_filament_switcher and enable_filament_dynamic_map as project
  config that persists with the project and restores from a saved 3mf, and
  force both back to false on every project/printer/CLI load path. Live
  device sync is the only thing that sets them true.

GUI:
- Sidebar sync activates the switch from live device state, attributes each
  AMS to the extruder its input track feeds, shows a floating status icon
  (ready / not-calibrated), and surfaces a one-time tip / not-calibrated
  warning.
- Send dialog gains a non-blocking slice-vs-hardware mismatch warning and a
  blocking error when a slice needs dynamic nozzle mapping but the switch is
  missing or not set up.
- AMS load/unload guards, AMS-view routing glyph + un-calibrated banner +
  hidden external-spool road, and mapping-popup external-spool lockout.
- Filament pickers collapse the per-extruder split into a single deduplicated
  "AMS filaments" group with a smart-assign toggle when the switch is ready.
- Firmware-upgrade panel lists the O2L-FTS accessory and its version.
- Device-provided filament-change steps (ams.cfs) drive the change-step
  display when firmware sends them, including the three switch steps.
- "Load current filament" asks which extruder to feed via a
  FeedDirectionDialog when the switch is calibrated.

Inert without the accessory: every path is gated on the switch being
installed (MQTT aux bit 29, default off) or ready, both project flags default
false, and the per-extruder AMS attribution is byte-identical, so AMS state,
the send/load UI, and sliced g-code are unchanged for every printer that does
not report a Filament Track Switch.
2026-07-09 18:57:05 +08:00
Andrew 6daef171c1 Add actions speed dial 2026-07-09 16:21:53 +08:00
bc6ffcfb31 Anisotropic surfaces + Separated Infills (remake) (#11682)
Co-authored-by: Rodrigo Faselli <162915171+RF47@users.noreply.github.com>
Co-authored-by: Ian Bassi <ian.bassi@outlook.com>
2026-07-08 15:40:19 -03:00
SoftFever 28b7127150 feat(gui): multi-nozzle UI for H2C/A2L
Multi-nozzle sync widget, AMS rack-nozzle mapping popup, calibration rework, send-dialog nozzle mapping and extruder-count UI. Includes the fix to persist the AMS sync badge on filament cards (H2C/A2L and direct-sync printers).
2026-07-09 01:16:26 +08:00
Kris Austin b58025575d fix: isolate calibration temp paths per user (#14619)
* fix: isolate calibration temp paths per user

The calibration temp files under <temp>/calib were file-scope statics
initialized before set_temporary_dir() runs at startup, so they kept
using the shared system temp root and missed the per-user isolation
added in #14607. On Linux every account shares /tmp, so the first user
to calibrate owns /tmp/calib and later users fail to write there, the
same cross-user collision #14607 fixed for model backups, STEP import,
and part skip.

Build the paths lazily from temporary_dir() instead, through a
calib_temp_dir() accessor and a calib_temp_file() join helper. The base
becomes <temp>/orcaslicer_<uid>/calib on Linux and is unchanged on
Windows, where the temp dir is already per user.

Also make StoreParams::path a std::string rather than a non-owning
const char*. The calibration code had to keep a std::string alive
solely to feed that pointer, and the field was uninitialized by
default; owning the string removes the lifetime hazard for all three
callers and makes the entry guard a reliable empty() check. Confined to
the 3mf project exporter (three callers, two internal reads); no
on-disk, format, or ABI impact.

Follows up on #14607 per @Noisyfox's review suggestion.
2026-07-08 21:14:05 +08:00
anjis cab62070b5 Fix garbled Chinese filenames when importing ZIP files. (#14633)
* Fix garbled Chinese filenames when importing ZIP files.

* fix: avoid repeated ZIP path CRC calculation
2026-07-08 20:24:55 +08:00
SoftFever 5ba5c6672d Fix reload from disk for STEP models after reopening a project (#12992) (#14591)
* Fix reload from disk for STEP models after reopening a project (#12992)

reload_from_disk matched reloaded source volumes with an exact
source.input_file string comparison. After a project is saved and
reopened, the stored source path is only the filename (the default,
non-full-path save) while a freshly re-imported volume carries a full
path, so the comparison never matched: reload fell into fail_list and
the "locate file" dialog was effectively useless for STEP models.

Fall back to a case-insensitive filename comparison when the exact
paths differ, so the existing same-folder source lookup (and the
locate dialog) can reload the model. Projects that stored absolute
source paths still match exactly as before; no 3mf format change.

* Add Preferences option to store full source paths in projects

Expose the existing export_sources_full_pathnames setting (previously
only editable in the config file) as a checkbox under Preferences >
General > Project. Enabling it stores absolute source paths in saved
projects, so "Reload from disk" works when the source file is kept in
a different folder than the project (companion to #12992).
2026-07-05 16:40:00 +08:00
Ian Bassi 61168cdb6f Do not reduce speed for calibrations (#13658) 2026-07-03 17:27:18 -03:00
Ian Bassiandyw4z 8309a9e8ee Exposing STEP import values (#14484)
Co-authored-by: yw4z <ywsyildiz@gmail.com>
2026-07-03 17:19:24 -03:00
SoftFever 4e26e7233e Merge branch 'main' into feat/plugin-feature 2026-07-04 00:19:39 +08:00
TheLegendTubaGuy a564a01013 fix: preserve PA batch speed and accel overrides (#14540)
* fix: preserve PA batch speed and accel overrides

* Remove broken ModelConfig set_config_values
2026-07-03 16:28:57 +08:00
Ian Chua ecddf3d18f feat: Python Plugins 2026-07-02 17:49:36 +08:00
yw4z 49fe64cb07 Fix: Filament section not foldable on launch for toolchanger / idex printers (#14406)
* init

* Update Plater.cpp
2026-07-01 12:21:40 +03:00
SoftFever 14e572db5f Add nozzle flow variant & make some options multi-variant (#13712)
# Description

Port BBS per-extruder config variants toggle, thanks Bambu!

Also fix invalid num error when resetting multi-variant filament
overrides.

TODOs:

- [x] Make more configs multi-variant (such as speeds)
- [x] Add flow variant (normal/high flow) combo box
- [x] Add botton to sync config to other variant


# Screenshots/Recordings/Graphs

<img width="846" height="1494" alt="image"
src="https://github.com/user-attachments/assets/47abf053-f5b8-4c86-ac0b-c0323ed8b242"
/>

<img width="1478" height="1189" alt="707420e5be01c30af3e6ede1f3dc9b67"
src="https://github.com/user-attachments/assets/11268712-da65-42ab-9cb8-3cede7790a5c"
/>

<img width="1478" height="1189" alt="81d5d3877f4d5bf9dccd44d7f0b30aa7"
src="https://github.com/user-attachments/assets/cda5ea51-07c3-48fc-bfbb-1428dca14e26"
/>


## 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)
Fix #10336
2026-06-28 22:30:40 +08:00
yw4z b06305f990 Plate toolbar improvements and fixes (slice button, keep view angle on slice, review button for failed plates, percentage and improve failed state) (#14292)
* Update Plater.cpp

* init

* Revert "Update Plater.cpp"

This reverts commit ae515bc7a4.

* fix empty plate showing as failed

* keep zooming on slice

* update

* add hover effect for active plate

* fix condition and match code

* Update GLCanvas3D.cpp

* fix button colors

* add hover effect to border of plate stats button

* fix scrollbar disappear while clicking plate buttons

* Update GLCanvas3D.cpp

* fix slicing percent for new plates

* update

* Update GLCanvas3D.cpp

* update plate states on config change

* fix non functional scrollbar
2026-06-25 22:31:33 +08:00
SoftFever 688127af5b Specify plate index for the 3mf workflow (#14404)
feat: forward plateindex for index-coded .gcode.3mf uploads

Gcode inside a .gcode.3mf is index-coded (Metadata/plate_<N>.gcode) and a
bundle may carry several, so the upload must name which plate to print —
even a single-plate bundle, since its entry is still indexed.

A 1-based plate index is stored in PrintHostUpload::extended_info when use_3mf
is set; the OctoPrint and Moonraker hosts forward it as a `plateindex` form
field. Servers that don't use it ignore the unknown field, so the plain G-code
path is unchanged.
2026-06-25 22:02:19 +08:00
Noisyfox 981cd599d5 It is in fact obj config 2026-06-22 20:51:40 +08:00
SoftFever 8522cc5f67 fix 1. default_acceleration was set to 20000 in calib_cornering 2. pa_pattern should use obj_config 2026-06-22 18:14:39 +08:00
SoftFever ca388f2d9e Merge branch 'main' into pr/Noisyfox/13712 2026-06-22 10:56:11 +08:00
Noisyfox ba12608e4a Don't allow adding more colors for non-semm printers on obj import color remapping dialog (#14275) 2026-06-21 18:20:58 +08:00
Ian Bassi 514ab02525 Localizations refactor (#14254) 2026-06-18 09:13:51 -03:00
raistlin7447 a587859e84 Fix: show all print validation warnings instead of only the last (#14112) 2026-06-18 12:45:26 +08:00
Alexandre Folle de MenezesandSoftFever 4535f19501 Misc fixes to GUI strings (#14047)
* Degrees symbol don't need localization

* The Z when referring to the axis should be uppercase

* Fix the spelling of "GitHub" to camelcase

* Unify the casing of mouse button shortcuts

* Always use G-code with an hyphen

* Fix the spelling of "restricted"

* More grammar fixes

* add missing modifications

---------

Co-authored-by: SoftFever <softfeverever@gmail.com>
2026-06-17 17:55:32 +08:00
SoftFever 9eeb73b68b feat: Support 3MF as g-code (use_3mf option) (#14238)
* feat: add support for 3MF file format in printer configurations and export options

* fix file extension

* enable 3mf for X Max 4

* disable use_3mf for X Plus 4

* Fixed an issue where `label_object_enabled` was not properly propagated to 3mf

* enable exclude object for Max 4

* remove hardcoded use 3mf for flashforge, move them to the new printer profiles config
2026-06-17 15:39:40 +08:00
yw4z 9bcee518f8 Filament list improvements (Filament counter & Auto unfold & Scroll to end of list on changes) (#14158)
* Update Plater.cpp

* filament counter
2026-06-14 12:04:34 +08:00
yw4z 5f8b48473a Show printer name on titlebar of printer section while its folded (#14148) 2026-06-13 20:45:42 +08:00
foXaCe d641ca598a i18n(fr): fix untranslated UI strings, extract hardcoded ones, complete French catalog (#14164) 2026-06-11 17:10:31 -03:00
spr0u ff4147ede3 fix: stuck hover state after opening printer preset dialog (#14082)
* fix: stuck hover state after opening printer preset dialog
2026-06-07 15:24:17 +08:00
Argo 2a08bf026f Bugfix: VFA calibration disables input shaping (Marlin 2) (#14079)
VFA calibration does not disable input shaping anymore
2026-06-07 14:12:44 +08:00
fcfadf0e8c Creality K-series support: LAN discovery + CFS filament sync + filament profiles (#13752)
## 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](https://harktech.co.uk/tools/orca-k2/screenshots/orca-k2-discovery-dialog.png)
| **Discovery dialog** — `Browse...` flow on a `host_type=crealityprint`
printer. Click → ~5–10 s LAN scan → K2 found with model + hostname + IP.
|
| ![Filament sidebar populated from
CFS](https://harktech.co.uk/tools/orca-k2/screenshots/orca-k2-cfs-sync-filaments.png)
| **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 showing
Mainsail](https://harktech.co.uk/tools/orca-k2/screenshots/orca-k2-device-tab-mainsail.png)
| **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>
2026-06-07 13:16:50 +08:00