Document filament compatibility specificity and preset naming conventions

This commit is contained in:
SoftFever
2026-09-20 22:36:45 +08:00
parent b4b4438a47
commit cb98d82023
5 changed files with 130 additions and 4 deletions
+5 -1
View File
@@ -21,6 +21,7 @@ Paths below are relative to this skill. Commands run from the repository root.
| Add a printer or nozzle; change models, variants, assets or extruder vectors | [machine-profiles.md](references/machine-profiles.md) |
| Add a quality tier or tune a process | [process-profiles.md](references/process-profiles.md) |
| Create a vendor bundle; diagnose loading or inheritance; migrate preset names | [vendor-bundle.md](references/vendor-bundle.md) |
| Name a preset; check what a name must equal | [naming.md](references/naming.md) |
| Change ids; diagnose AMS identity | [ids.md](references/ids.md), then `docs/HLSD/filament_id.md` for identity changes |
| Review a profile diff | [review-checklist.md](references/review-checklist.md) |
| Run checks, interpret failures, test another tree or verify in the app | [validation.md](references/validation.md) |
@@ -44,7 +45,10 @@ Paths below are relative to this skill. Commands run from the repository root.
update in-tree references too. See [migration rules](references/vendor-bundle.md#renamed_from).
6. **Compatibility uses exact printer variant names.** Every instantiated non-library filament
needs a non-empty `compatible_printers` in its own file. Library fallbacks may omit it;
library printer-specific tunes use a non-empty list. Keep same-product tunes disjoint.
library printer-specific tunes use a non-empty list. One variant may be claimed by only one
profile per filament product (`filament_id`); an overlap is resolved by moving the variant to the
most specific preset, which is preferred over deleting a profile. See
[one variant, one profile](references/filament-profiles.md#overlapping-coverage-one-variant-one-profile-per-product).
7. **Preset values are strings or arrays of strings.** Use `"instantiation": "false"`, not `false`.
Model `nozzle_diameter` is a `;`-separated string; machine `nozzle_diameter` is an array.
Wrong types can abort loading; see [failure scopes](references/vendor-bundle.md#failure-modes-ranked-by-blast-radius).
@@ -103,6 +103,57 @@ name.
- Copying a base's full printer list onto a nozzle-specific variant produces duplicate combobox entries —
a real shipped bug twice over.
## Overlapping coverage: one variant, one profile per product
`filament_id` is the **product** key, not the preset key — every variant of one product shares it
(`<filament_vendor>/<filament_type>/<name-before-@>`). So if one printer variant appears in the
`compatible_printers` of two presets of that product, the slicer cannot tell them apart at AMS match time.
The C++ validator reports `Ambiguous AMS filament match: N presets share filament_id "X" … printer "Y"`.
`orca_profile_tool.py check` does **not** see it and passes. Resolve the overlap by **specificity**: keep
the variant on the most specific profile and remove it from every more general one. Deleting a profile is
the least preferred fix — moving coverage keeps the tune that users rely on.
Judge specificity from the profile's `compatible_printers` — how many variants it actually covers — and
use the name only as a secondary, easily-vague hint; decide by the lists, with a best judgement call on
the name. Naming conventions differ by vendor: BBL's is the reference (`@<Vendor> <Model>` for a whole
model, `@<Vendor> <Model> <nozzle> nozzle` for one variant, `@<Vendor>` for a vendor-wide generic), but
others vary (`@<printer model>`, a printer serial, or Creality's `@<Model>-all`). A name never overrides
the list — see [preset naming](naming.md) for the shapes.
Specificity, most to least:
1. **Variant-specialized** — lists a single printer variant (BBL-style
`... @<Vendor> <Model> <nozzle> nozzle`).
2. **Model-specialized** — lists the variants of one printer model (BBL-style `... @<Vendor> <Model>`).
It should cover every variant of its model, not only the nozzle it was authored for.
3. **Family / series** — lists variants spanning a printer family or series.
4. **Generic / catch-all** — vendor-wide, covering many unrelated models (often the bare
`Generic <mat> @<Vendor>`).
Rules:
- A model-specialized profile is extended to **all** variants of its model, and each variant it thereby
starts covering is removed from the family and generic profiles that also listed it — including variants
that had no overlap before. Apply it per nozzle, not just 0.4.
- Apply it **per product**: trim only the material that has a specialized profile from the generic; a
material whose product has no specialized profile keeps the variant in the generic.
- Never strip coverage a variant has nowhere else to get. If a variant has no variant-level specialized
profile, the next level down keeps it; when the model has specialized profiles, the model-level one wins
over the family/generic.
- Moving coverage is preferred over deleting. If a profile must be deleted, remove the more general
one, not the specialized profile that carries the tune.
- After moving coverage, repoint the affected `default_filament_profile` (machine) and clean the model's
`default_materials`: they should name the most specific profile that covers the variant, and should not
keep generic entries that no longer cover the model. This rule applies equally when adding or fixing
defaults.
Multiple profiles of one product with **disjoint** `compatible_printers` is the intended end state.
Adding coverage to the specialized profile and removing it from the generic is the preferred direction.
**Detection caveat:** `orca_profile_tool.py check` is blind to this; only the C++ validator behind the full
`./scripts/check_profile.sh` reports it (`validate_system`). Always confirm with that, not the vendor-scoped
loop.
## Alias shadowing
A printer-specific filament in either the library or a vendor bundle supersedes the library fallback
@@ -0,0 +1,60 @@
# Preset naming
A preset's `name` is the loader's key, not decoration. The index registers it; `inherits`,
`compatible_printers` and the `default_*` keys reference it by the exact string; `renamed_from` depends
on it; and `setting_id` / `filament_id` hash it (see [ids.md](ids.md)). Two presets of one type in a
bundle may not share a name (`check_preset_name_uniqueness`). Treat a name change as an identity change,
not a relabel.
Naming is convention only where the loader does not parse it. What the loader actually acts on:
| Type | Shape | Acted on |
| --- | --- | --- |
| `machine_model` | `<Model>` | the exact string, named by a variant's `printer_model` |
| `machine` | `<Model> <nozzle> nozzle` | the exact string, named by `compatible_printers`; `printer_variant` must equal a nozzle diameter |
| `process` | `<lh>mm <Quality> @<target>` | the exact string when referenced or selected; the `@<target>` half is a label |
| `filament` | `<Product> @<target>` | text before the first `@` is the **alias**, used for shadowing; the rest is a label |
## `machine_model`
`<Model>` — the vendor-prefixed model name (`Bambu Lab X1 Carbon`, `Creality K1`, `Prusa CORE One`). A
variant names it verbatim in `printer_model`; a mismatch makes the variant invalid. `check_name_consistency`
forces the index entry to equal the file's `name`, and the variant's `printer_model` targets this string
([A `machine_model` is not a config preset](machine-profiles.md#a-machine_model-is-not-a-config-preset)).
It is also the `<Model>_cover.png` and bed-asset stem.
## `machine` (variant)
`<Model> <nozzle> nozzle` is near-universal (`Bambu Lab X1 Carbon 0.4 nozzle`). `printer_variant` holds
the bare nozzle (`0.4`) and must be an exact member of the model's `nozzle_diameter` list — the hard
rules are in [The `machine` variant](machine-profiles.md#the-machine-variant). Casing varies
(`nozzle` / `Nozzle`): match the bundle, not this page. A variant that is not nozzle-specific (a special
toolhead, a multi-material build) may drop the suffix — still an exact reference. Bases are named
`fdm_machine_common` / `fdm_<vendor>_common`.
## `process`
`<layer height>mm <quality> @<target>` — [process-profiles.md](process-profiles.md#naming) has the
quality ladder and the `fdm_process_*` base names. The `@<target>` is a human label, not a reference: it
usually does not equal a real variant, and compatibility comes from the resolved `compatible_printers`
list or condition.
## `filament`
`<Product> @<target>`. The product half is what `filament_id` hashes and what survives as the **alias** up
to the first `@`; the target half is a label except for reserved forms:
- `@base` — a non-instantiated product root. `@base` is convention; a base is really identified by
`instantiation: "false"` and no `setting_id` ([the three-part shape](filament-profiles.md#the-three-part-shape)).
- `@System` — the OrcaFilamentLibrary selectable shim. The literal `Generic <mat> @System` is
load-bearing for 3MF/project recovery, beyond the alias rule ([alias shadowing](filament-profiles.md#alias-shadowing)).
- `@<Vendor>`, `@<Vendor> <Model>`, `@<Vendor> <Model> <nozzle> nozzle` — printer tunes, BBL's shape.
Other vendors differ (a bare model, a printer serial, Creality's `@<Model>-all`). Specificity is judged
from `compatible_printers`, not the name
([one variant, one profile](filament-profiles.md#overlapping-coverage-one-variant-one-profile-per-product)).
## Not the same as the filename
The loader keys off `name`, and a filename that disagrees usually still loads. Index `name` must equal the
file's `name`, and the filename should match `sub_path`; a mismatch that differs only in case breaks
another platform ([cross-platform paths](validation.md#cross-platform-paths)).
@@ -79,8 +79,15 @@ and written in the preset's own file — golden rule 6, with the flattened-vs-ow
inherited or copied the base's full printer list, and for two presets of one product with overlapping
lists — duplicate combobox entries and an ambiguous AMS match.
Two presets of one product (`filament_id`) must not share a variant. Resolve it by specificity: move the
variant to the most specific preset and remove it from the more general ones — preferred over deleting a
profile. Then repoint the machine's `default_filament_profile` and the model's `default_materials` at the
profile that now covers it. See
[one variant, one profile](filament-profiles.md#overlapping-coverage-one-variant-one-profile-per-product).
*Why:* real shipped bugs twice (`b7b3418baf` "showing up everywhere", `ff83aa41ef` duplicate Flashforge
entries).
entries). The Python `check` passes on an overlap; only the full `check_profile.sh` (`validate_system`)
reports `Ambiguous AMS filament match`.
## 6. Model ↔ variant ↔ process consistency
@@ -128,7 +135,11 @@ numbers nobody measured.
## 11. `default_materials` (checked by CI)
`check` fails on a `default_materials` / `default_filament_profile` name that resolves to no system
filament, so a dangling entry no longer reaches review. Scope the run while working on one vendor:
filament, so a dangling entry no longer reaches review. When compatibility moves between profiles of a
product, the machine's `default_filament_profile` and the model's `default_materials` must be repointed at
the most specific profile that still covers the variant, dropping generic entries that no longer apply —
the same [specificity rule](filament-profiles.md#overlapping-coverage-one-variant-one-profile-per-product)
applies when adding or fixing defaults. Scope the run while working on one vendor:
```bash
python3 scripts/orca_profile_tool.py check --vendor "<Vendor>" # py -3 on Windows
@@ -223,7 +223,7 @@ Keep stems tidy too, but a space immediately before `.json` is not a trailing pa
| `references unknown compatible_printers "<p>"` | the printer was renamed or deleted; fix the reference |
| `references renamed compatible_printers "<old>" (now "<new>")` | in-tree references must name the current preset; `renamed_from` does not excuse them |
| `Filament preset "<f>" is missing compatible_printers setting` | non-library filaments need a non-empty list in their **own** file — the flattened-vs-own-key trap is in [filament-profiles.md](filament-profiles.md#compatible_printers) |
| `Ambiguous AMS filament match: N presets share filament_id "X" … printer "Y"` | make the lists disjoint, or fix an `inherits` pointing at another material's `@base` |
| `Ambiguous AMS filament match: N presets share filament_id "X" … printer "Y"` | make the lists disjoint by [specificity](filament-profiles.md#overlapping-coverage-one-variant-one-profile-per-product) — the specialized profile keeps the variant, the general ones drop it; prefer this over deleting a profile — or fix an `inherits` pointing at another material's `@base`. `orca_profile_tool.py check` does not catch this; only `validate_system` here does |
| `Layer height cannot exceed nozzle diameter.` / `Line width too small` | `Print::validate()` flow rules |
| `[ERROR] … no <V>.json list references it, so it never loads` | `update-index`, or delete the file |
| `[ERROR] … references it and it declares no profile type` | set the correct `type` explicitly, then `normalize` and `update-index` |