All 264 QD_* declarations re-derive from their family triples via
--remint Qidi. Only 8 family ids are new: most QIDI-brand products already
carried v3.2-minted ids on older printer series, so the QD-series
declarations converge onto them (QD_0..4_1_1 -> OFKIQO2W "QIDI PLA
Rapido"), and the six Generic families converge onto the shared generic
ids (Generic PLA -> OFDSrzZ8 etc.) by triple math -- no inherits or
compatible_printers changes anywhere.
--update-snapshot retires all 204 QD_* ids with mode-rule successors.
Audit: 204/204 non-null successors, every chain ends at a live id; the
four ids hardcoded in QidiPrinterAgent's non-numeric-series fallback
resolve to the OFL generics (QD_1_0_1 -> OFDSrzZ8, ...). The v4.1 agent
hook translates device-composed QD_* ids through these entries at
runtime, so box behavior is preserved on updated clients.
Known accepted residue (plan v4 SS4): three case/spelling family splits
keep distinct ids for one product line each -- QIDI PC-ABS-FR (series
1-2) vs QIDI PC/ABS-FR (series 3-4) vs Qidi PC-ABS-FR (X-Plus 4), and
QIDI TPU 95A-HF vs Qidi TPU 95A-HF. Renames are ruled out; the ledger's
per-series successors keep each device slot resolving to the right
presets, and a future upstream name unification self-heals through
content addressing.
The code<->ledger lockstep test is now active (un-skipped).
Gates: --check 0; orca_extra_profile_check 0/0; 117 script tests OK
(0 skipped); validator base, -f tree-wide, -v Qidi all exit 0;
libslic3r_tests green; Qidi profile diff is filament_id-value-only.
Qidi.json version bumped.
Brings in 560 commits (merge base 2026-07-04 .. origin/main af9fd10d7a).
19 conflicts resolved; the other 138 touched files auto-merged.
Conflict resolutions
- Snapmaker/Polymaker (7): main normalised JSON key order in #15039 while this
branch inserted filament_id/filament_vendor. Took main's key order and kept
this branch's values, inserting a single filament_id key rather than letting
git's line merge leave duplicate "from"/"instantiation" keys.
- re3D rPETG @0.8/@1.75 nozzle (2): main renamed these from "re3D Greengate
rPETG @*" and re-vendored GreenGate3D -> re3D (#15169). Git's rename-aware
merge produced a file with two filament_vendor keys; took main's version
wholesale instead. The id is reconciled by the tooling, not by hand.
- re3D rPP (1): kept main's inherits change (fdm_filament_pet -> fdm_filament_pp,
local filament_type override dropped) and its widened compatible_printers.
The flattened type is still PP, so the product triple and id OFfHGM1D are
unchanged.
- re3D Greengate rPETG.json, Afinia {ABS+,ABS,PLA,TPU,Value ABS,Value PLA}.json
(7 modify/delete): accepted main's deletions. The Afinia ids are not orphaned
- the surviving @HS presets resolve the same triple and already carry the
same ids, so nothing is retired.
- .github/workflows/check_profiles.yml: kept both main's new "validate slice"
step and this branch's tree-wide filament-subtype check.
- tests/libslic3r/CMakeLists.txt: kept both test_filament_id_succession.cpp and
main's test_preset_diff.cpp.
Verified
- No conflict markers; all 12795 profile JSONs parse with no duplicate keys.
- All branch artifacts (tooling, snapshot, ledger, doc, tests) intact and
unmodified by the merge.
- The succession-ledger C++ call sites survived main's refactors; audited
Preset.{cpp,hpp}, PresetBundle.cpp, DeviceManager.cpp, PresetComboBoxes.cpp,
CaliHistoryDialog.cpp, MoonrakerPrinterAgent.cpp against base/ours/theirs.
- scripts/tests: 115/116 pass.
Known follow-up: assign_filament_ids.py --check reports 243 errors, all from
filament data main added in the last month (BBL/addnorth, Qidi X5/Plus 5,
Snapmaker U1, re3D). The single failing unit test is the live-tree conformance
test asserting that count is zero. Reconciliation lands separately.
* re:3D profile updates.
- Replace vendor-specific "re3D Greengate rPETG" filament with a generic "re3D rPETG" (base + @0.8/@1.75 nozzle variants), matching the naming convention used for rPLA/rPETG elsewhere in the re:3D vendor
pack.
- Add fdm_filament_pp as a proper filament-type parent and switch re3D rPP to inherit from it instead of overriding filament_type on top of fdm_filament_pet.
- Added filament_type to the specific printer JSON file and removed from the base printer JSON file [fixes Issue#14693]
- Updates to speeds and accelerations for re:3D profiles, moved from common to machine processes [closed: PR#14259]
- Updates to fdm profile filename format so that it lists the filename and extruder number in the sliced .gcode file
* Fix setting IDs
* Add rename from for changed material names.
* Add the Qidi Plus 5
* Remove ignored profiles
Qidi didn't register these, so they are essentially dead weight.
* Set Qidi profile version to 02.04.00.10
* Fix redundant QIDI startup tool changes
Guard Q2, X-Max 4, and X-Plus 4 filament-change G-code so same-tool startup selections do not run the full cut, unload, and purge sequence.
* Guard Q2C against redundant startup tool changes
Skip the complete filament-change sequence when the requested tool is already selected during startup.
* Bump Qidi profile version
Adds a printer option that picks up the new tool without a blocking temperature
wait, travels to the wipe tower, and waits there right before purging, parked
beside the tower so the ooze from the heat-up lands next to it rather than on the
model. The incoming filament's target is raised ahead of the tool change, so the
heat-up overlaps both the change itself and the travel to the tower.
Off by default, and only offered for multi-extruder printers using a Type 2 wipe
tower; the generic toolchanger profile enables it.
* update snapmaker profiles. largely ported for Snapmaker Orca fork
* update prime volume
* set precise_outer_wall to 1
* Update per-material multi-tool ramming to the filament library
* Add per-filament overrides for toolchange retraction
* Set toolchange retraction per filament for Snapmaker U1
* set default support type to tree
* format snapmaker profiles
The eight presets added in 0545750c1b never got ids: the six iQ processes
had none, and K1 SE 0.8 / V-Core 4 0.8 carried ids copied from the presets
they were duplicated from — K1 SE 0.8 still shared K1C 0.8's id. Regenerated
with scripts/assign_vendor_setting_ids.py; none of the eight have shipped in
a release, so no existing id changes meaning.
Declare support_cooling_filter=1 on the three profiles (0.2/0.6/0.8
variants inherit from 0.4) and insert the cooling-filter conditional
into the H2D and H2S machine start g-code, inside the low-chamber-temp
airduct branch:
{if(cooling_filter_enabled)} M145.2 P0 F0 {else} M145.2 P0 F1 {endif}
H2D Pro intentionally gets no g-code edit: its duct firmware takes the
filter mode over the device channel only, so the flag merely enables
the toggle.
Impact on existing users at default settings: H2D/H2S start g-code gains
exactly one line (M145.2 P0 F1, filter off) in the cool-chamber branch;
nothing is removed or reordered. The existing support_air_filtration=1
overrides are deliberately kept so exhaust-fan behavior for ABS-class
filaments is unchanged, even though the machine-tab row is hidden while
the cooling-filter toggle is shown.
cooling_filter_enabled existed as a config option but was shown nowhere,
and there was no capability flag to gate it. The cooling filter and air
filtration are alternative accessories sharing the same duct, so a
printer declares one or the other.
- new hidden printer capability flag support_cooling_filter
- "Use cooling filter" toggle in the Accessory group, shown only when
the printer supports it; the air-filtration toggle hides in that case
(no vendor restriction: third-party printers keep air filtration)
- explicit defaults (0) in the common machine base
- H2C declares support_cooling_filter=1 instead of support_air_filtration;
its start-gcode already carries the cooling-filter conditional, so the
toggle is functional. On H2C this drops the two exhaust-fan lines that
air filtration emitted for ABS-class filaments, matching the printer's
actual duct accessory; H2C is new on this branch so no existing user
output changes.
Printers without the flag keep exactly the previous accessory UI and
g-code.
New printer option fan_direction (undefine/left/right/both, default
undefine) declares which side the auxiliary part-cooling airflow comes
from. When set and the printer has an auxiliary fan, auto-orient adds a
yaw rotation so the dominant overhang area faces the airflow, and newly
added primitive shapes are pre-oriented the same way (except the Cube,
whose axis-aligned bounding box the pressure-advance pattern calibration
depends on).
- FanDirection enum + fan_direction printer option (Accessory group,
enabled only with auxiliary_fan)
- orient engine: weighted overhang areas per candidate, yaw-direction
search, vertical rotation applied on top of the primary orientation;
the cooling weights are taken from the candidate actually chosen,
including the flat-bottom tie-break
- orient_for_cooling() for primitive placement
- set fan_direction=left on H2C/H2D/H2D Pro/X1/X1E/P1S 0.4 profiles
(X1C/H2S/P2S/X2D/Qidi X-Max 4 already carried the key, which now
takes effect)
With fan_direction unset or no auxiliary fan the vertical rotation stays
identity and auto-orient results are unchanged; slicing and g-code are
never affected.
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.
* fix profile reference for Creality
* fix profile reference for Blocks
* fix profile reference for OrcaArena
* fix profile reference for re3D
* fix profile reference for Chuanying
* fix profile reference for Prusa
* fix profile reference for Wanhao France
* fix profile reference for MagicMaker
* fix profile reference for Afinia
Remove the ABS/ABS+/PLA/TPU/Value ABS/Value PLA filament presets that referenced the non-existent "Afinia H400 Pro" printer. The real printer is "Afinia H+1(HS)", already served by the @HS filament variants.
* fix profile reference for Comgrow
Remove the orphaned "0.20mm Standard @Comgrow T500 1.0" process preset and its process_list entry. Its only compatible printer "Comgrow T500 1.0 nozzle" never existed (the T500 model defines nozzle diameters 0.4/0.6/0.8 only).
* always run check_preset_references
Every remaining legacy filament_id outside the BBL/QD_* islands re-derives
from its product triple (filament_vendor / filament_type / family name),
completing the content-addressed id model of filament_id_plan_v3.md:
- Relocation pre-step: 14 fdm_filament_* template forks (Cubicon x3,
Prusa x6, RH3D x6 minus the pc fork already re-homed) stop declaring
ids; the 16 presets that rode Prusa's forks now declare the id they
already resolved (verified zero effective-id drift over all 5892
instantiated presets).
- --drop-redundant-ids: 6 Custom/MyToolChanger generics drop copied GF
ids and ride their OFL families.
- --remint over all 62 non-island vendors: 2647 declarations re-derived;
identical products converge cross-bundle (showcase: PolyLite PLA is now
OF5CgdDq in OrcaFilamentLibrary, Qidi, OrcaArena and Snapmaker).
- Prusament @XL completions surfaced by the relocation: filament_vendor
["Prusa Polymers"] on the 8 @XL declarers; Prusament PA-CF typed
PA11-CF (the product is Prusament PA11CF) and PC-CF typed PC-CF
(-CF family typed as base polymer); each family converges on one id.
- Succession: 331 ids retired with mode-rule successors, 355 never-shipped
v1 mints forgotten with chain splicing, 151 GF-shaped ids released to
the island space with hints, 27 curated BBL-generic -> OFL-generic
hints (GFL99 -> OFDSrzZ8 class). New --retire "OLD=NEW" maintenance
mode records lineage for OGFC99/OGFG99/OGFN99 (the shipped ids of OFL's
Generic PC/PETG/PA in released versions, whose claims migrated in v3.1
while Cubicon's inert fork declarations kept them alive).
- Retiring the P-hex system ids removes the last system ids from
check_ams_filament_valid's destructive P-gate.
- AMS-ambiguity fixes surfaced by convergence (validator -f): 4 presets
riding another family's id through inherits now declare their true
family id (Elegoo Generic ASA-CF/PETG-CF, Snapmaker PolyLite Dual PLA /
PolyLite J1 PLA); 9 Cubicon @base presets and Dremel Generic PLA, which
duplicate their per-printer variants on the same printers, split onto
the salt-1 iteration of their triple (sanctioned by the mint-conformance
check; --remint now leaves salt-conformant declarations alone).
Gates: assign_filament_ids --check 0; orca_extra_profile_check 0;
116 python unit tests; config-equivalence over all 5892 instantiated
presets (byte-identical configs except the 14 sanctioned Prusament
vendor/type corrections; setting_id and compatible_printers unchanged;
per-family convergence and ledger conservation verified); profile
validator base/-f/-r(BBL)/-r(Qidi) all green; libslic3r_tests 48610
assertions; Moonraker OFL generic map check; custom-preset fixture
archives v1.9.0-v2.4.1.
Phase v3.1 of filament_id_plan_v3.md: every OFL-declared filament_id
re-derives from its product triple; the succession ledger absorbs the old
ids. Config-equivalence verified: flattened effective configs differ ONLY
in filament_id (284 consistent old->new changes tree-wide, including every
vendor preset that rides an OFL family), zero config/compatible_printers/
setting_id drift.
Structural pre-step (id-value-neutral, verified): OFL generic family ids
move from the shared fdm_filament_* template bases onto the product-named
"Generic X @System" presets, so the v3 triple's family component is the
product name, not an internal file name (12 relocations; 2 dead duplicate
declarations on fdm_filament_pa/pet pruned; every consumer chain itemized
first - the +12 instantiated_with_id entries are this deliberate pattern,
matching the 11 generics that already declared on @System).
fdm_filament_pc keeps its declaration this phase: 7 Prusa presets (Prusa
Generic PC, Prusament PC Blend) inherit it directly and re-home in the
v3.2 Prusa worksheet; its transitional id is documented in the plan.
Re-mint: 301 declarations re-derived (e.g. Generic PLA OGFL99 ->
OFDSrzZ8 = mint("filament_product/Generic/PLA/Generic PLA")). Snapshot:
1477 ids (+300/-292). Ledger:
- 230 shipped ids retired with mode-rule successors (OGF* library ids,
OFLSBS99, DREMC/FILAR/AliZ/eSUN/... legacy strings). DREMC010 had been
shared by a PPA-CF and a TPU family - a data bug this split resolves;
its successor follows its only shipped claim (DREMC PPA-CF).
- 25 GF-shaped ids OFL had copied from the Bambu catalog (GFOT00x
Overture, GFSEP0xx) are RELEASED to the BBL island space with hints at
the re-minted families - never retired, so a future legitimate BBL
catalog addition is never blocked; plus an explicit GFOT001 ->
OFxA1p01 hint (Overture PLA Pro, still live in BBL).
- 37 never-shipped v1 branch mints dropped from lineage
(--forget-never-shipped; they exist in no release, no forwarding
needed).
- OGFC99/OGFG99/OGFL96/OGFN99/OGFSNL08 stay live (still declared by
vendor bundles); they retire in v3.2 when those declarers re-mint.
Gates: 106 unit tests OK; --check exit 0; orca_extra_profile_check exit 0;
validator -l 2 / -f tree-wide / -r BBL+Qidi exit 0; Moonraker OFL map
check resolves all 29 aliases against the re-minted presets; flatten
equivalence pre/post as above; snapshot regen idempotent.
Implements phase v3.0 of filament_id_plan_v3.md - tooling and client
prerequisites. No filament_id values change in this commit.
Tooling (scripts/assign_filament_ids.py; 106 unit tests):
- The mint key becomes "filament_product/<filament_vendor>/<filament_type>/
<family_name>", resolved loader-faithfully from the declarer's flattened
config - bundle-independent and content-addressed; identity fixes re-id
by design and are made safe by the succession ledger. --mint now takes
the triple.
- The snapshot gains "triples" and "triple_exceptions" sections, folded
into the equality gate: any vendor/type/name change surfaces as a
reviewable snapshot diff. Check 3 rewritten to triple-mint conformance
with (id, triple) grandfathering; check 5 generalized from OFL generics
to every OFL-riding vendor preset; new check 8 (triple integrity) and
check 9 (succession integrity).
- The retired ledger moves to resources/profiles/retired_filament_ids.json
so it ships with the app; schema {claims, successor} plus cross-island
"hints". The 14 v1 entries are migrated with mode-rule successors.
Vanished ids in a foreign island's space (GF*/QD_*) are RELEASED with a
hint instead of retired: the island catalog owns them and may
legitimately (re)ship them, which check 4 must never block.
- New maintenance modes: --remint VENDOR, --drop-redundant-ids VENDOR,
--add-hint "OLD=NEW", and --update-snapshot --forget-never-shipped FILE
(never-shipped ids drop from lineage; chains splice through them).
Runtime (C++):
- Succession helpers in libslic3r/Preset (pure chain-follow + lazy ledger
load from resources), consulted only on resolution miss in
get_filament_by_filament_id, both AMS sync predicates,
add_ams_filaments, setting_id_to_type, and the calibration-history
lookup; behavior is byte-identical while the ledger has no matching
entry. Catch2 coverage in tests/libslic3r.
- W1 hardening: check_ams_filament_valid no longer remote-wipes trays or
rewrites temps for P-shaped ids that a system preset carries (ten such
system ids ship today); the size==8 && [0]=='P' assert is relaxed; the
unguarded filament_list find deref in the temp-equation check returns
non-destructively on a miss.
- MoonrakerPrinterAgent: the 23 hardcoded OFL generic ids are replaced by
a runtime lookup of "Generic <family> @System" (id-equivalent on
today's shipped profiles, follows future re-mints automatically);
scripts/test_moonraker_lane_data.py derives its expectations from the
shipped profiles and gains --check-ofl-map.
Profile data (W3 - type is now a key component, so type bugs are fixed
before any re-mint):
- 17 same-name-different-type groups corrected across 50 files (OFL
Generic PETG-CF/PE-CF/PP-CF; Flashforge ASA Basic/ASA-CF/ABS-CF/HIPS/
PAHT-CF/PLA Silk; FusRock PAHT; Creality Generic PA6-CF; InfiMech PETG;
Anycubic TPU 95A / TPU for ACE; Prusa Generic PA-CF/PLA-CF) - every
value validated against MaterialType::all(); 3 Snapmaker U1 roots gain
their missing filament_vendor. Flattened-config equivalence vs the
previous commit: exactly the 54 intended diffs, zero BBL.
- doc/developer-reference/filament_id.md rewritten for the v3 rule.
Ambiguous type divergences (Prusa Generic TPU/TPU HF FLEX-vs-TPU, FusRock
S-Multi/S-PAHT) and all same-type vendor-tag divergences are deferred to
the v3.2 vendor worksheets, catalogued with analysis.