Skip to content

Creality K3 (F039) support, draft, needs real K3 test - #622

Draft
aceRage wants to merge 6 commits into
cursor/creality-cfs-sync-d523from
cursor/creality-k3-f039-38ab
Draft

aceRage wants to merge 6 commits into
cursor/creality-cfs-sync-d523from
cursor/creality-k3-f039-38ab

Conversation

@aceRage

@aceRage aceRage commented Oct 19, 2026 •

Copy link
Copy Markdown
Owner

Description

Depends on #625 (merge #625 first) via #619. Merge the Creality stack (#618 → #616 → #619) then this.

#625 adoption: direct-rack (K3) printers opt in with third_party_map_read_only(). mapping[i] is warning_slot_position() (identity T-number) so tiles, highlight and mapping_warning() agree (F13). filament_mapping() stays empty; start stays opGcodeFile. K3 mapping_warning() is kept next to #625's third_party_mismatch_warning(). T1–T3 counts only lines whose previous significant line is ; custom gcode end (allowing blanks, ;_FORCE_RESUME_FAN_SPEED, and M106/M107 including P-indexed); a preceding T0 block cannot credit a later T1–T3 (F10). Slot.name tile labels apply only when direct_rack (F1).

Stacked PR. Base is cursor/creality-cfs-sync-d523 (head of the Creality stack: #618 → #616 → #619). Must land after #619. Do not merge onto main first.

Draft Creality K3 (model code F039) support. The K3 is on pre-order (not shipping). It is a Klipper 4-nozzle KliTek toolchanger: four independent nozzles, each fed from its own filament holder, one printing at a time, ~5 s swaps, no CFS.

This fork already handles that machine class for the Snapmaker U1 (single_extruder_multi_material=false, four nozzle_diameter entries, filament i → physical Ti). The K3 reuses that path. Creality Print's filament_map / filament_is_mixed machinery is not ported. No shared slicer code is changed in a way that would alter U1 G-code.

Screenshots/Recordings/Graphs

None. No hardware. The send dialog shows K3 holders read-only (what's loaded in each nozzle) and states that T0–T3 are as sliced.

Art (F9): Creality K3_cover.png and Creality K3_thumbnail.png are K2 Plus placeholders. They need real K3 art before this is more than a draft.

Tests

Catch2 cases were added in existing files only (no CMake edits). The full [CrealityK3] slice case was not compiled — this environment has no build/, /opt/edgeslicer-deps, or /opt/edgeslicer-app. The T-count helper was compiled standalone and passed.

  • tests/slic3rutils/printhost_devices_tests.cpp: F039 is a known direct-rack model (not CFS, not K1-family); resolve_model("", "Creality K3") → F039; gcode root is the stack default /mnt/UDISK; opGcodeFile start; parse_direct_rack_response accepts four 1-slot racks or one 4-slot box and skips the type-1 external rack; status_from_direct_rack is never CFS; holder labels are Nozzle N (T{n}); mismatch helper warns on empty / type+colour (tolerant RGB distance) / filament 5+ with no nozzle. Identity fill: warning_slot_position for read-only mapping.
  • tests/libslic3r/test_wipe_tower_no_sparse_gcode.cpp [CrealityK3]: four-cube K3 system-profile slice asserts the ported start sequence (START_PRINT EXTRUDER_TEMP=, BED_TEMP=, M104 S140, M104 S220 T, G1 X120 Y0 E15), END_PRINT / G1 X130 Y255, T0–T3 tool lines, and a K3 change-filament marker in the ; custom gcode end adjacency immediately before each T1/T2/T3. Only T lines whose most recent significant line is ; custom gcode end (allowing blanks, ;_FORCE_RESUME_FAN_SPEED, and M106/M107 including M106 P2 S255) are counted. Start G-code T and M104 T3 are not counted. A preceding T0 block cannot credit a later T1–T3 (F10). Marker: G1 Y… Z… F30000 (the template's Y±5 dodge) or I0.86 J0.86 P1 (spiral fallback). Not a bare Z…F30000 (travel z-hop uses that too).

orca_extra_profile_check.py --vendor Creality --check-filaments --check-materials --check-obsolete-keys --check-assets exits 0. Warning count is 714 on this branch and on cursor/creality-cfs-sync-d523. No printed line names K3.


Review 4/3 (da5e12a325) — panel-adoption B1 / F1

  • B1. count_k3_change_t_lines also skips M106/M107 (including P-indexed, e.g. M106 P2 S255) between ; custom gcode end and T, because CoolingBuffer replaces ;_FORCE_RESUME_FAN_SPEED with those commands. Synthetic cases: marker then M106 S128 then T2; marker then M106 P2 S255 + M107 then T1. Start T3, M104 T3, and T0 no-credit remain. Standalone helper compile passed.
  • F1. ds.label = s.name only when direct_rack, so it cannot override Happy Hare and AFC slot reading for the Moonraker send dialog #612's 1A–1D grouping for QIDI/HH/AFC. Comment on use_third_party_map_panel(): once Happy Hare and AFC slot reading for the Moonraker send dialog #612 merges it must be cfs || direct_rack || qidi_box || happy_hare || afc.

Review 2/3 (dbefe65b9a)

  • B1 / F6 redo. Tool-change G-code is written before T. The test now looks in the nearest preceding custom-gcode block for the K3 dodge G1 Y… Z… F30000 or I0.86 J0.86 P1, and requires one such block per T1/T2/T3.

Review 1/3 follow-ups (8e4d32d9d5 on 35d4c1caf9)

  • F6. Superseded by the 2/3 redo above (the after-T scan was wrong).
  • F7. Holder colour compare uses colour_rgb_dist_sq (the same RGB helper auto_match_index uses). Near-identical shades (about 32 RGB units) do not warn. Filament 5+ emits “has no matching nozzle” instead of being ignored.
  • F8. Send-dialog note and mismatch lines are _L() / format_wxstr literals so xgettext can extract them. Status.note stays English for Catch2.
  • F9. Cover and thumbnail are K2 Plus placeholders and need real K3 art (listed above).

Review 1/3 blockers (35d4c1caf9)

  • B1. Direct-rack UI is honest. Holders are read-only. No dropdown, no closest-colour prefill. filament_mapping() returns empty so history / Snapmaker unload cannot record a fake remap. Start stays opGcodeFile. Note says mapping is set when slicing (assign filaments to extruders); T0–T3 go to nozzles 1–4; send does not remap G-code. Type/colour mismatch vs the T-number holder is a warning only.
  • B2. Added Creality K3_cover.png and Creality K3_thumbnail.png (K2 Plus stand-ins; see F9). Dropped obsolete keys: filament_load_time / filament_unload_time from Hyper PLA; overhang_speed_classic / overhang_totally_speed from the K3 process files.
  • B3. Creality.json version 02.03.02.06 → 02.03.02.07.
  • F1. Bed model/texture are K2/Hi 260×260: creality_hi_buildplate_model.stl + creality_k2_buildplate_texture.svg (not the K1 235×250 assets).
  • F3. Holder labels are Nozzle 1 (T0) … Nozzle 4 (T3).
  • F5. [CrealityK3] asserts the K3 start/tool-change sequence (see Review 2/3 for the tool-change half).

Validator output

$ python3 scripts/orca_extra_profile_check.py --vendor Creality --check-filaments --check-materials --check-obsolete-keys --check-assets
[INFO] Checking profiles ...
… pre-existing obsolete filament_load_time / filament_unload_time on K1/K2/SPARKX/Ender profiles (no K3 files) …
==================== SUMMARY ====================
[INFO] Checked vendors     : 1
[SUCCESS] Files with errors   : 0
[WARNING] Files with warnings : 714
=================================================
exit 0

Same command on cursor/creality-cfs-sync-d523 (#619): errors 0, warnings 714, same printed obsolete-key set. No new warnings.


Sources (Creality Print, AGPL)

Inspected on CrealityOfficial/CrealityPrint (current default branch at the time of this work):

Item Where
Machine + model resources/profiles/Creality/machine/Creality K3.json, Creality K3_model.json (nozzle_diameter 0.4×4, single_extruder_multi_material=false)
Process resources/profiles/Creality/process/0.20mm Standard @Creality K3.json (and siblings)
Filament resources/profiles/Creality/filament/Hyper PLA @Creality K3.json (and Generic PLA/PETG/ABS/ASA/TPU)
Scope / send revert doc/creality-k3-current-direct-rack-scope-plan.md; SendToPrinter revert c709a2aaf (K3-specific filament_maps / open_cfs start was reverted; start is opGcodeFile)
Device panel PrinterBoxFilamentPanel.cpp (model == "F039")
M109 / K3 gate MachineVender::is_creality_k3 used only for OozePrevention::post_toolchange M109
F039 notes doc/bugfixes/F039-K3-*.md
Vendor index Creality Print Creality.json K3 entries

Upstream OrcaSlicer has no K3 profile.

What was adapted

  • Profiles under resources/profiles/Creality/ (machine model + 0.4 nozzle, four processes, six filaments) and surgical inserts in Creality.json after the K2 SE counterparts. Schema adapted to EdgeSlicer: scalar nozzle_type / nozzle_volume; host_type / printer_agent = crealityprint; printer_model = Creality K3 (the stack preset fallback). Start / end / change_filament_gcode ported from Creality Print and credited in the machine JSON. tool_change_temprature_wait=0 (profile-gated M109 fix → M104). purge_in_prime_tower=0 on the machine. machine_tool_change_time=5.
  • Model detection (CrealityPrintModel.hpp): direct_rack_models {F039 → K3} separate from cfs_capable_models. is_known_model includes F039 only (not the display name). resolve_model reverse-maps Creality K3 / K3 → F039. omit_upload_path("F039") is false. G-code root: stack default /mnt/UDISK (see unverified).
  • Send / device: no new WebSocket start message. K3 stays on opGcodeFile + enableSelfTest. #618 deadline/cancel rules unchanged. Probe uses /info + boxsInfo; F039 is parsed by parse_direct_rack_response (does not reuse CFS 4-slot padding). If holders are reported they are shown read-only via the shared Bambu-style swatch map for third-party send dialogs (CANVAS, U1, QIDI Box) #625 panel; filaments stay T0–T3 as sliced. No "Use CFS". Calibrate before printing is kept because Creality Print puts enableSelfTest on generic opGcodeFile.
  • Slicer: no shared wipe-tower / OozePrevention C++ changes (Creality Print's WipeTowerCreality zhop is not ported). U1 / Snapmaker files untouched.

Unverified (needs a real K3)

  • G-code root. Creality Print's F039 sources do not name a K3-specific path. Used the stack default /mnt/UDISK. Flag this on first hardware test.
  • Holder / boxsInfo schema. Parser accepts both "four type-0 boxes, one material each" and "one type-0 box, four materials" and skips type 1. On-wire layout is unknown.
  • Network protocol. Assumed the same port-9999 opGcodeFile as other non-CFS Creality machines after the SendToPrinter revert. No K3 start-message capture.
  • No hardware. No printer, no send, no print.
  • Catch2 slice test not compiled. T-count helper compiled standalone; [CrealityK3] slice binary not built.
  • Creality Print's K3 wipe-tower C++ (zhop) was not ported; only profile settings (enable_prime_tower, purge_in_prime_tower=0, ooze / standby).
  • Cover/thumbnail are K2 Plus placeholders and need real K3 art.

Real-K3 smoke checklist

When a K3 is available:

  1. Load Creality K3 0.4 nozzle + 0.20mm Standard @Creality K3 0.4 nozzle + four filaments. Confirm Check profiles / profile validator is clean.
  2. Slice a 4-colour model. Confirm T0–T3, START_PRINT EXTRUDER_TEMP= / M104 S140 / M104 S220 T, a G1 Y… Z… F30000 (or I0.86 J0.86 P1) custom block immediately before each T1–T3, prime tower, and M104 (not wait-M109) on tool changes.
  3. Confirm a Snapmaker U1 4-colour slice is byte-identical to cursor/creality-cfs-sync-d523 (this PR must not change U1 G-code).
  4. Connect the printer. Confirm /info model is F039 and the preset fallback Creality K3 → F039.
  5. Confirm the send dialog: no "Use CFS"; "Calibrate before printing" present; holders read-only via the shared map panel if reported; note says as-sliced T0–T3; no mapping dropdown; a type/colour mismatch vs the T-number holder warns only; filament 5+ warns it has no nozzle.
  6. Confirm gcode lands under /mnt/UDISK/printer_data/gcodes/ (or record the real root).
  7. Send a single-colour then a 4-colour job. Confirm start is opGcodeFile (no colorMatch / multiColorPrint / CFS fields) and the printer starts.
  8. Confirm a ~5 s nozzle swap and that T0–T3 as sliced print the right colours (mapping is set in the slicer).
  9. Cancel a send mid-probe / mid-start and confirm #618 deadline/cancel still applies (no hang).
  10. Run libslic3r_tests "[CrealityK3]" and printhost_devices_tests (F039 / direct-rack sections) after a real compile.
  11. Replace the K2 Plus cover/thumbnail placeholders with real K3 art.
Open in Web Open in Cursor 

cursoragent and others added 4 commits October 19, 2026 02:47
Treat the K3 as a U1-style four-nozzle toolchanger (no CFS). Profiles
and start/end/tool-change G-code are adapted from Creality Print (AGPL).
F039 is a known model with the stack default /mnt/UDISK gcode root;
start stays on opGcodeFile. Catch2 covers model detection, holder parse,
and a four-colour T0-T3 slice.

Co-authored-by: aceRage <aceRage@users.noreply.github.com>
Direct-rack holders are read-only; T0-T3 stay as sliced and
filament_mapping() is empty so history cannot record a fake remap.
Add a K3 cover (K2 Plus stand-in), drop obsolete profile keys, bump
Creality.json to 02.03.02.07, use the K2 260x260 bed, and tighten
the K3 slice asserts.

Co-authored-by: aceRage <aceRage@users.noreply.github.com>
Assert a Z+F30000 or I0.86 spiral on the motion after T1-T3, not
strings that also appear in start/end G-code. Compare holder colours
with the existing RGB-distance helper and warn when filament 5+ has
no nozzle. Format the send-dialog note and mismatch lines with _L()
so xgettext can extract them.

Co-authored-by: aceRage <aceRage@users.noreply.github.com>
change_filament_gcode is emitted before the T command. Scan the
nearest preceding custom-gcode span for the K3 Y-dodge
(G1 Y… Z… F30000) or I0.86 J0.86 P1 spiral, and require one such
block per T1/T2/T3.

Co-authored-by: aceRage <aceRage@users.noreply.github.com>

aceRage commented Oct 19, 2026

Copy link
Copy Markdown
Owner Author

Code Evaluator review: re-review 3/3 @dbefe65b9a, FAIL (1 blocker, test only). The 3 re-review limit has been reached, so this goes to the upstream reviewer with the open findings below. The code itself is clean: no libslic3r, U1 or CFS changes, and the profile validator exits 0 with no new warnings.

B1, a one-line test fix: the [CrealityK3] count check (test_wipe_tower_no_sparse_gcode.cpp :777-778) also counts the start G-code's bare T3. With a prime tower on a non-Bambu printer and priming at 0, GCode.cpp:3435-3438 uses the last used extruder (3 with four extruders, ToolOrdering.cpp:1403-1406) as initial_no_support_extruder (:3442-3443). The K3 start G-code emits T[initial_no_support_extruder] ('Creality K3 0.4 nozzle.json':96), which is a bare T3 outside any custom block. So k3_blocks_before_t comes out one short of tool_changes and :778 fails even when every change runs. To fix it, ignore T lines before the first ; custom gcode start or the first layer marker, or only count T lines whose most recent non-blank line is ; custom gcode end (allowing ;_FORCE_RESUME_FAN_SPEED in between).

Open follow-ups:

  • F10: a T1-3 change with no block of its own, straight after a T0 change, could wrongly get credit for the T0 block.
  • F9: Creality K3_cover.png and _thumbnail.png are K2 Plus placeholders and need real K3 art.

Still owed: Edge CI, MSVC Release+Debug, Catch2 run, a real K3 send and print (send protocol, /mnt/UDISK root and boxsInfo holder layout are unverified), and a U1 byte-identity check. It must land after the Creality stack (#618 -> #616 -> #619).

cursoragent and others added 2 commits October 19, 2026 14:59
…f039-38ab

Adopt the shared Bambu-style filament map panel for K3 direct-rack
printers (third_party_map_read_only). Read-only mapping[i] is the
identity T-number slot so tiles, highlight and mapping_warning() agree.
filament_mapping() stays empty; start remains opGcodeFile.

T1-T3 counts only lines whose previous non-blank is "; custom gcode end"
(allowing ;_FORCE_RESUME_FAN_SPEED). A preceding T0 block cannot credit
a later T1-T3 (F10).

Conflicts in PrintHostDialogs kept K3 mapping_warning() next to the
#625 third_party_mismatch_warning() helper.

Co-authored-by: aceRage <aceRage@users.noreply.github.com>
Russ #622 B1: skip M106/M107 (including P-indexed) between '; custom gcode end'
and T so real tool changes still count after CoolingBuffer replaces
;_FORCE_RESUME_FAN_SPEED. Start G-code T, M104 T3, and T0 reset stay excluded.
F1: apply the Slot.name tile label only on direct_rack so #612's 1A-1D grouping
is not overridden.

Co-authored-by: aceRage <aceRage@users.noreply.github.com>

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants